#include "threadsafe.h"
#include "file.h"
#include "miner.h"
#include "htmlobject.h"
#include "xml.h"
#include "htmlform.h"
#include "time.h"
#include "snprintf.h"
#include "dbms.h"
#include "url.h"
#include "properties.h"
#include "finder.h"
#include "ftp.h"
#include "hash.h"
#include "http.h"
#include "queue.h"
#include "lzw.h"



#define   deleteRegisterA while(registerA){tmp1=registerA;registerA=registerA->next;delete tmp1;}
#define   deleteRegisterB while(registerB){tmp1=registerB;registerB=registerB->next;delete tmp1;}
#define   deleteRegisterC while(registerC){tmp1=registerC;registerC=registerC->next;delete tmp1;}

#define  rmQuotes(bf,p)	if(p->mine(*bf,"\"`*`\"")){	delete bf;bf=p->getValueFinal(0);trim(bf);}


Buffer* urlEncode(char*,int);


ULONG getSignature(ULONG fcs,UCHAR *cp,int len);
char* xauth="x-authorized";

mutex *editLock=0;

Buffer* getXauth()
{
	char tmv[10];
	char codev[10];
    Time *t=new Time();
    snprintf(tmv,10,"%08lx",t->inSeconds());
	char *tc=t->rfcFormat();
    ULONG code=getSignature(172226,(UCHAR*)tc,strlen(tc));
	delete t;
    snprintf(codev,10,"%08lx",code);
	Buffer *tmp=new Buffer(17);
	char* string=*tmp;
	int j=0;
	for(int i=0;i<8;++i){
		string[j++]=codev[i];
		string[j++]=tmv[7-i];
	}
	string[j++]=0;
	return tmp;
}

int htoi(char*);

int xauthenticated(genericObject* obj)
{
	char *xa=obj->showValue(xauth);
	if(xa && *xa){
		char tmv[16];
		*tmv=0;
		char codev[16];
		int j=0;
		for(int i=0,k=7;xa[i]!=0 && i<16;){
			codev[j++]=xa[i++];
			tmv[k--]=xa[i++];
		}
		codev[j]=0;
		tmv[8]=0;
		ULONG a=htoi(tmv);
		if(a==0)
			return 0;
		ULONG b=htoi(codev);
		Time *t=new Time();
		int d=t->inSeconds()-a;
		if(d>-600 && d <600){
			t->SetTime(a);
			char* tc=t->rfcFormat();
			a=getSignature(172226,(UCHAR*)tc,strlen(tc))-b;
		}
		delete t;
		if(a==0)
			return 1;
	}
	return 0;
}



/*
   ftp x=user:paswd@www.software.ibm.com/pub
*/




class wSpace:public virtual ThreadSafe{
   enum{MINPATTERNS=32};
   Buffer* sb;
   int maxp;
   int pcount;
   char** patterns;
   char** replacements;
   Buffer** Bufferpatterns;
   Buffer** Bufferreplacements;
   int *psize;
   int *rsize;
   char name[16];
   public:
   wSpace(char* name=0);
   ~wSpace();
   char* getName() { if(*name) return name;return 0;}
   int setPattern(char* p,char* r);
   int setPattern(Buffer* p,Buffer *r);
   char** getPatterns() { return patterns;}
   char** getSubstitutes() {return replacements;}
   int* getPsize() { return psize;}
   int* getRsize() { return rsize;}
   int getSize() { return pcount;}
   int getPatternSize() { return maxp;}
   int getIndex(char,int*);
   };


wSpace::wSpace(char* n)
:sb(new Buffer(MINPATTERNS*6*sizeof(void*))),maxp(0),pcount(0)
{
 if(n!=0){
  strncpy (name,n,15);
  name[15]=0;
 }else
  *name=0;
 char* tmp=*sb;
 Bufferpatterns=(Buffer**)tmp;
 Bufferreplacements=Bufferpatterns+MINPATTERNS;
 patterns=(char**)(Bufferpatterns+MINPATTERNS*2);
 replacements=(char**)(Bufferpatterns+MINPATTERNS*3);
 psize=(int*)(Bufferpatterns+MINPATTERNS*4);
 rsize=psize+MINPATTERNS;
}



int wSpace::getIndex(char c,int *count)
{
		  int e=pcount-1;
		  int b=0;
		  int d;
		  while(e>=b){
		     int m = (b+e)/2;
             if((d=(c-*patterns[m]))<0)
              b=m+1;
             else
             if(d>0)
              e=m-1;
             else{
			  for(b=m+1;(b<pcount) && (*patterns[b]==c);++b);
			  for(;(m>0) && (*patterns[m-1]==c);m--);
			  *count=b;
		      return m;
			 }
		  }
		  *count=0;
		  return 0;
}
            
/*

void wSpace::setEol(char* e)
{
  setPattern("\n",e);
  setPattern("\r",e);
  setPattern("\r\n",e);
  setPattern("\r\r",e);
  setPattern("<br>",e);
}


void wSpace::setPara(char* p)
{
  setPattern("\r\n\r\n",p);
  setPattern("\n\n",p);
  setPattern("\r\n   ",p);
  setPattern("\r\n     ",p);
  setPattern("\r   ",p);
  setPattern("\r     ",p);
  setPattern("\n   ",p);
  setPattern("\n     ",p);
  setPattern("<p>",p);
}


void wSpace::setTextMode()
{
  setEol("\r\n");
  setPara("\r\n   ");
  setPattern("<hr>","----------------------------------\r\n");
}


void wSpace::setHtmlMode()
{
  setEol("<br>");
  setPara("<p>");
}
  
*/


int wSpace::setPattern(char* p,char *r)
{
	int id=setPattern(new Buffer(p,strlen(p)+1),new Buffer(r,strlen(r)+1));
	return id;
}


int wSpace::setPattern(Buffer* p,Buffer *r)
{
	EnterCritSec();
	char *s=*p;
	int z=p->getSize()-2;
	if(((z+2)==r->getSize()) && (memcmp(*r,s,z+1)==0)){
		int i;
		for(i=0;i<pcount;++i){
			if((z==psize[i]) && (memcmp(patterns[i],s,z+1)==0))     
				break;
		}
		if(i<pcount){
			delete Bufferpatterns[i];
			delete Bufferreplacements[i];
			pcount--;
			if(i<pcount){
				memcpy(Bufferpatterns+i,Bufferpatterns+i+1,sizeof(Buffer*)*(pcount-i));
				memcpy(Bufferreplacements+i,Bufferreplacements+i+1,sizeof(Buffer*)*(pcount-i));
				memcpy(patterns+i,patterns+i+1,sizeof(char*)*(pcount-i));
				memcpy(replacements+i,replacements+i+1,sizeof(char*)*(pcount-i));
				memcpy(psize+i,psize+i+1,sizeof(int)*(pcount-i));
				memcpy(rsize+i,rsize+i+1,sizeof(int)*(pcount-i));
			}
			ExitCritSec();
			delete p;
			delete r;
			return 0;
		}
	}
	if((pcount*6*sizeof(void*)) >= (ULONG)(sb->getSize())){
		Buffer *tmp=new Buffer((pcount+MINPATTERNS)*6*sizeof(void*));
		Buffer** d=(Buffer**)(char*)*tmp;
		Buffer** s=(Buffer**)(char*)*sb;
		Bufferpatterns=d;
		memcpy(d,s,pcount*sizeof(void*));
		s+=pcount;
		d+=pcount+MINPATTERNS;
		Bufferreplacements=d;
		memcpy(d,s,pcount*sizeof(void*));
		s+=pcount;
		d+=pcount+MINPATTERNS;
		patterns=(char**)d;
		memcpy(d,s,pcount*sizeof(void*));
		s+=pcount;
		d+=pcount+MINPATTERNS;
		replacements=(char**)d;
		memcpy(d,s,pcount*sizeof(void*));
		s+=pcount;
		d+=pcount+MINPATTERNS;
		psize=(int*)d;
		memcpy(d,s,pcount*sizeof(void*));
		s+=pcount;
		d+=pcount+MINPATTERNS;
		rsize=(int*)d;
		memcpy(d,s,pcount*sizeof(void*));
		delete sb;
		sb=tmp;
	}
	int b,c;
	for(b=getIndex(*s,&c);b<c;++b){
		if((z==psize[b]) && (memcmp(patterns[b],s,z+1)==0))     
			break;
	}
	if(b==c){
		int e=pcount-1;
		b=0;
		int d;
		while(e>=b){
			int m = (b+e)/2;
			if((d=(*s-*patterns[m]))<0)
				b=m+1;
			else
				if(d>0)
					e=m-1;
				else{ 
					b=m;
					break;
				}
		}
		if(b<pcount){
			memmove(patterns+b+1,patterns+b,sizeof(void*)*(pcount-b));
			memmove(Bufferpatterns+b+1,Bufferpatterns+b,sizeof(void*)*(pcount-b));
			memmove(replacements+b+1,replacements+b,sizeof(void*)*(pcount-b));
			memmove(Bufferreplacements+b+1,Bufferreplacements+b,sizeof(void*)*(pcount-b));
			memmove(psize+b+1,psize+b,sizeof(int)*(pcount-b));
			memmove(rsize+b+1,rsize+b,sizeof(int)*(pcount-b));
		}
		Bufferpatterns[b]=p;      
		Bufferreplacements[b]=r;
		patterns[b]=s;
		replacements[b]=*r;
		rsize[b]=r->getSize()-1;
		psize[b]=z;
		pcount++;
	}else{
		delete p;
		delete Bufferreplacements[b];
		Bufferreplacements[b]=r;
		replacements[b]=*r;
		rsize[b]=r->getSize()-1;
	}
	if(rsize[b]>maxp)
		maxp=rsize[b];
	ExitCritSec();
	return b;
}


wSpace::~wSpace()
{
   for(int i=0;i<pcount;++i){
      delete Bufferpatterns[i];
      delete Bufferreplacements[i];
   }
   delete sb;
}


Buffer* convertText(char* b ,int size,wSpace* s)
{
	if(size>0){
		register int n=0;
		int *index,mz,tz;
		int offset=s->getPatternSize();
		if(offset<32)
			offset=32;
		char* *pattern=s->getPatterns();
		char* *outtext=s->getSubstitutes();
		int *psize=s->getPsize();
		int *rsize=s->getRsize();
		int count;
		Buffer *inx=new Buffer(s->getSize()*sizeof(int));
		index=(int*)((char*)*inx);
		memset(index,0,mz=inx->getSize());
		tz=size+size/10+offset;
		Buffer *tmp=new Buffer(tz);
		tz-=offset;
		char *e=*tmp;
		int v=0;
		int i,j,k;
		for(i=0,j=0,k=-1;i<=size;++i){
			if(n==0){
				v=s->getIndex(b[i],&count);
			}
			int l=0,p=v;
			for(;p<count;++p){
				if(index[p]==n){
					if(pattern[p][n]==b[i] && i < size){
						if(n==psize[p])
							k=p;
						else{
							index[p]++;
							l=1;
						}
					}
				}
			}
			if(l==0){
				if(k>=0){
					memcpy(e+j,outtext[k],l=rsize[k]);
					i-=n-index[k];
					j+=l;
					k=-1;
				}else{
					i-=n;
					e[j++]=b[i];
				}
				if(n>0){
					n=0;
					memset(index+v,0,(count-v)*sizeof(int));
				}
				if(j>=tz){
					Buffer *newb=new Buffer(tz=(tz+tz/10+2*offset));
					tz-=offset;
					memcpy(*newb,e,j);
					delete tmp;
					tmp=newb;
					e=*tmp;
				}
			}else
				n++;
		}
		delete inx;
		e[j]=0;
		tmp->setSize(j);
		return tmp;
	}else
		return new Buffer("",1);
}



#define MAXMODE 64

wSpace *modes[MAXMODE];

void saveMode(wSpace *x)
{   
	if(x){
		char *n=x->getName();
		if(n==0)
			delete x;
		else{
			int i=0;
			for(;modes[i]!=0 && i<MAXMODE;++i){
				if(modes[i]==x)
					return;
				if(stricmp(modes[i]->getName(),n)==0){
					delete x;
					return;
				}
			}
			if(i==MAXMODE)
				delete x;
			else
				modes[i]=x;
		}
	}
}


wSpace* getMode(char* modename)
{
	for(int i=0;modes[i]!=0 && i<MAXMODE;++i){
		if(stricmp(modes[i]->getName(),modename)==0){
			return modes[i];
		}
	}
	return 0;
}

Buffer* replaceXmlText(char *b,int size)
{
	static char *xmlname="xmltext";
	wSpace *x=getMode(xmlname);
	if(x==0){
		x=new wSpace(xmlname);
		saveMode(x);
	}
	x->setPattern("&amp;","&");
	x->setPattern("&lt;","<");
	x->setPattern("&gt;",">");
	x->setPattern("&quot;","\"");
	x->setPattern("&apos;","'");
	x->setPattern("&#;","&#");
	x->setPattern("\r\n","\n");
	x->setPattern("\r","\n");
	return convertText(b ,size,x);
}

Buffer* convertMailText(char *b,int size)
{
	static wSpace *x;
	if(x==0){
		x=new wSpace("mail");
		x->setPattern("\r\n","\r\n");
		x->setPattern("\r","\r\n");
		x->setPattern("\n","\r\n");
		x->setPattern("\n.","\r\n..");
		x->setPattern("\r.","\r\n..");
		x->setPattern("\r\n.","\r\n..");
	}
	return convertText(b ,size,x);
}

Buffer* replaceTextXml(char *b,int size)
{
	static char *xmlname="textxml";
	wSpace *x=getMode(xmlname);
	if(x==0){
		x=new wSpace(xmlname);
		saveMode(x);
	}
	x->setPattern("&","&amp;");
	x->setPattern("<","&lt;");
	x->setPattern(">","&gt;");
	x->setPattern("\"","&quot;");
	x->setPattern("'","&apos;");
	x->setPattern("\r\n","\r\n");
	x->setPattern("\r","\r\n");
	x->setPattern("\n","\r\n");
	return convertText(b ,size,x);
}


Buffer* replaceCdataXml(char *b,int size)
{
	static wSpace *x;
	if(x==0){
		x=new wSpace("xml");
		x->setPattern("]]>","]]&gt;");
	}
	return convertText(b ,size,x);
}

htmlBuffer* filter(htmlBuffer* value,int *mode,wSpace *xSpace)
{
	htmlBuffer *r=0;
	htmlBuffer *re;
	while(value){
		htmlBuffer *tmp1=value->next;
		if(value->isValid()){
			vFile *outFile=0;
			htmlBuffer *z=0;
			Buffer *tmp=0;
			if(*mode>=2){
				tmp=urlEncode(*value,value->getSize()-1);
			}
			else{
				File* fd=value->getFile();
				if(fd==0){
					tmp=convertText(*value,value->getSize()-1,xSpace);
				}else{
					outFile = new vFile(fd->getRealName());
					Buffer *outbuffer=new Buffer(BFSIZE);
					fd->seekTo(0);
					int nread;
					do{
						nread=fd->read(*outbuffer,BFSIZE);
						if(nread>0){
							tmp=convertText(*outbuffer,nread,xSpace);
							outFile->write(*tmp,tmp->getSize()-1);
							delete tmp;
						}
					}while(nread==BFSIZE);
					outFile->close();
					delete outbuffer;
				}
			}
			if(outFile)
				z=new htmlBuffer(outFile);
			else{
				if(tmp)
					z=new htmlBuffer(tmp);
			}
			if(z!=0){
				if (r==0)
					r=z;
				else
					re->next=z;
				re=z;
			}
		}
		delete value;
		value=tmp1;        
	}
	if(*mode>=2)
		*mode-=2;
	return r;
}


class ftpObject : public genericObject{
   enum FTPSTAT{NOTCONNECTED=0,LOGGEDIN=1};
   ftpClient *ftp;
   FTPSTAT ok;
   char user[32];
   char pswd[32];
   char filespec[32];
   FileList *files,*nextFile;
   int event;
   int login();
   void getFiles();
   Buffer *getFolder();
   public:
   ftpObject(Buffer *,char*,int);
   ~ftpObject() { delete ftp; deleteFileList(files);}
   int putValue(Buffer*,htmlBuffer*);
   htmlBuffer* getValue(htmlBuffer*);
   char getType() { return TYPFTP;}
   };



void ftpObject::getFiles()
{
	if(files==0){
		login();
		files=ftp->getFiles(filespec);
		nextFile=files;
	}
}

Buffer* ftpObject::getFolder()
{
	if(*ftp->getpwdstr()==0)
		login();
	char* p=ftp->getpwdstr();
	if(*p==0)
		return 0;
	int n=strlen(p);
	int i;
	for(i=n-1;i>=0;--i)
		if( p[i]== SLASH || p[i]==FSLASH){
			i++;
		    break;
		}
        if(i<0)
           i=0;
	if(p[i]!=0)
		return new Buffer(p+i,n-i+1);
	return 0;
}


ftpObject::ftpObject(Buffer *name,char* site,int eventh)
  : genericObject(name),ok(NOTCONNECTED),files(0),nextFile(0),event(eventh)
{
	miner *m=new miner();
	strcpy(user,"anonymous");
	strcpy(pswd,"caravan@somwhere.net");
	if(m->mine(site,"`*`:`*`\\@`*`/`*`")){
		char *host=m->getValue(2);
		if(*host){
			strcpy(user,m->getValue(0));
			strcpy(pswd,m->getValue(1));
			ftp=new ftpClient(host);
			if(*user && *pswd){
				ftp->setUser(user,pswd);
				if(ftp->login()){
					ok=LOGGEDIN;
					ftp->chDir(m->getValue(3));
				}
			}
		}
	}else
		if(m->mine(site,"`*`:`*`\\@`*`")){
			char *host=m->getValue(2);
			if(*host){
				strcpy(user,m->getValue(0));
				strcpy(pswd,m->getValue(1));
				ftp=new ftpClient(host);
				if(*user && *pswd){
					ftp->setUser(user,pswd);
					if(ftp->login()){
						ok=LOGGEDIN;
					}
				}
			}
		}else{
			if(m->mine(site,"`*`/`*`")){
				ftp=new ftpClient(m->getValue(0));
				if(ftp->login()){
					ok=LOGGEDIN;
					ftp->chDir(m->getValue(1));
				}
			}else
				ftp=new ftpClient(site);
		}
	delete m;
	filespec[0]=0;
}

int ftpObject::login()
{
	char *folder=0;
	if(ok==LOGGEDIN){
		return ftp->login();
	}
	ftp->setUser(user,pswd);
	if(ftp->login()){
		ok=LOGGEDIN;
		if(folder && *folder)
			ftp->chDir(folder);
		return 1;
	}
	return 0;
}



htmlBuffer* ftpObject::getValue(htmlBuffer* name)
{
	htmlBuffer *result=0;
	char buffer[16];
	char* n=*name;
	if(stricmp(n,"error")==0){
		result=ftp->getError();
	}else
	if(stricmp(n,"login")==0){
		login();
	}else
	if(stricmp(n,"passive")==0){
		ftp->setPassive();
	}else
	if(stricmp(n,"folder")==0){
		Buffer *fb=getFolder();
		if(fb)
			result=new htmlBuffer(fb);
	}else
	if(stricmp(n,"path")==0){
		if(*ftp->getpwdstr()==0)
			login();
		result=new htmlBuffer(ftp->getpwdstr());
	}else
	if(stricmp(n,"deleteFile")==0){
		if(files && nextFile){
			if(ftp->Delete(nextFile->getName())){
				if(files==nextFile){
					files=nextFile->next;
					delete nextFile;
					nextFile=files;
				}else{
					for(FileList *fl=files;fl!=0;fl=fl->next)
						if(fl->next==nextFile){
							fl->next=nextFile->next;
							delete nextFile;
							nextFile=fl->next;
							break;
						}
				}
			}
		}
	}else
	if(stricmp(n,"deleteFolder")==0){
			Buffer *pf=getFolder();
			if(pf!=0){
				if(ftp->CDup()){
						if(ftp->Rmdir(*pf)==0){
							ftp->chDir(*pf);
						}else{
							if(files){

								deleteFileList(files);
								files=0;
								nextFile=0;
							}
						}
				}
				delete pf;
			}
	}else{
		getFiles();
		if(stricmp(n,"type")==0){
			if(nextFile!=0){
				if(nextFile->getType()=='d')
					result=new htmlBuffer((char*)"folder");
				else
					result=new htmlBuffer((char*)"file");
			}
		}else
		if(stricmp(n,"filename")==0){
			if(nextFile!=0)
				result=new htmlBuffer(nextFile->getName());
		}else
		if(stricmp(n,"extension")==0 || stricmp(n,"extention")==0){
			if(nextFile!=0){
				char *e=nextFile->getName();
				int i;
				for(i=strlen(e);i>0;i--)
					if(e[i]=='.')
						break;
					if(e[i]=='.')
						result=new htmlBuffer(e+i+1);
			}
		}else
		if(stricmp(n,"Total")==0){
			FileList *result=files;
			int i;
			for(i=0;result!=0;i++)
				result=result->next;
			snprintf(buffer,16,"%d",i);
			return new htmlBuffer(buffer);
		}else
		if(stricmp(n,"nextfile")==0){
			while(nextFile) {
				nextFile=nextFile->next;
				if(nextFile==0 || nextFile->getType()=='-')
					break;
			}
		}else
		if(stricmp(n,"nextfolder")==0){
			while(nextFile) {
				nextFile=nextFile->next;
				if(nextFile==0 || nextFile->getType()=='d')
					break;
			}
		}else
		if(stricmp(n,"findnext")==0){
			if(nextFile!=0) {
				nextFile=nextFile->next;
			}
		}else
		if(stricmp(n,"findfirst")==0){
			nextFile=files;
		}else
		if(stricmp(n,"size")==0){
			if(nextFile) {
				snprintf(buffer,16,"%lu",nextFile->getSize());
				return new htmlBuffer(buffer);
			}
		}else
		if(stricmp(n,"file")==0){
			if(nextFile){
				File *f=ftp->getFile(nextFile->getName());
				if(f!=0)
					result=new htmlBuffer(f);
			}
		}else
		if(stricmp(n,"time")==0){
			if(nextFile) {
				if(nextFile->mdTime()==0){
					Time *t=ftp->getFileTime(nextFile->getName());
					if(t!=0){
						nextFile->setTime((ULONG)*t);
						delete t;
					}
				}
				snprintf(buffer,16,"%ld",nextFile->getTime());
				return new htmlBuffer(buffer);
			}
		}else
		if(stricmp(n,"date")==0){
			if(nextFile) {
				snprintf(buffer,16,"%ld",nextFile->getTime());
				return new htmlBuffer(buffer);
			}
		}
	}
	return result; 
}


int ftpObject::putValue(Buffer* name,htmlBuffer* val)
{
	if(val==0 || name==0){
		delete name;
		delete val;
		return 0;
	}
	char *n=*name;
	int result=0;
	if(stricmp(n,"debug")==0){
		ftp->setDebug(atoi(*val));
	}else
	if(stricmp(n,"user")==0){
		strcpy(user,*val);
		result=1;
	}else
	if(stricmp(n,"password")==0){
		strcpy(pswd,*val);
		result=1;
	}else
	if(stricmp(n,"filespec")==0){
		if(stricmp(filespec,*val)){
			strcpy(filespec,*val);
			if(files){
				deleteFileList(files);
				files=0;
			}
		}
		result=1;
	}else
	if(stricmp(n,"filename")==0){
		getFiles();
		for(nextFile=files;nextFile!=0;nextFile=nextFile->next){
			if(stricmp(nextFile->getName(),*val)==0)
				break;
		}
	}else
	if(stricmp(n,"file")==0){
		login();
		File *f=val->getFile();
		File* delf=0;
		if(f==0){
			f=new File(*val);
			if(f->exists()==0){
				delete f; 
				f=0;
			}else
				delf=f;
		}
		if(f!=0){
			if(ftp->putFile(f,event)){
				char *b=f->getRealName();
				ftp->setType('-');
				FileList *fl=ftp->getFiles(b);
				FileList *tmp=0;
				if(fl==0){
					fl=new FileList(b,f->size(),f->lastWriteTime(),0);
				}else{
					for(nextFile=fl->next;nextFile!=0;){
						tmp=nextFile;
						nextFile=nextFile->next;
						delete tmp;
					}				
					tmp=0;
				}
				for(nextFile=files;nextFile!=0;nextFile=nextFile->next){
					if(stricmp(nextFile->getName(),b)==0)
						break;
					tmp=nextFile;
				}
				if(nextFile==0){
					fl->next=0;
					if(tmp){
						tmp->next=fl;
					}else{
						files=fl;
					}
				}else{
					fl->next=nextFile->next;
					if(tmp){
						tmp->next=fl;
					}else{
						files=fl;
					}
					delete nextFile;
				}
				nextFile=fl;
			}
			delete delf;
		}
	}else
	if(stricmp(n,"type")==0){
		char c=ftp->getType();
		if(stricmp(*val,"folder")==0)
			ftp->setType('d');
		else
		if(stricmp(*val,"file")==0)
			ftp->setType('-');
		else
			ftp->setType('*');
		if(c!=ftp->getType()){
			if(files)
				deleteFileList(files);
			files=0;
		}
	}else
	if(stricmp(n,"folder")==0){
		int up=strcmp(*val,"..")==0;
		if(up==0 || ftp->cmpDir(*val)==0){
			if(ok!=LOGGEDIN)      
				login();
			if(up){
				Buffer *fb=getFolder();
				if(ftp->CDup()){
					if(files){
						deleteFileList(files);
						files=0;
						nextFile=0;
					}
					ftp->setType('d');
					files=ftp->getFiles("");
					if(fb!=0){
						for(FileList* fnext=files;fnext!=0;fnext=fnext->next){
							if(stricmp(fnext->getName(),*fb)==0){
								nextFile=fnext;
							}
						}
					}else
						nextFile=0;
				}
				delete fb;
			}else{
				if(ftp->chDir(*val)){
					if(files){
						deleteFileList(files);
						files=0;
					}
				}
			}
		}
	}else                                     
	if(stricmp(n,"newfolder")==0){
		login();
		if(ftp->Mkdir(*val))
			result=1;
	}else
	if(stricmp(n,"newfilename")==0){
		if(nextFile){
			if(ftp->Rename(nextFile->getName(),*val)){
				nextFile->setName(*val);
				result=1;
			}
		}
	}else
	if(stricmp(n,"persistent")==0){
		setPersistent(stricmp(*val,NULLVALUE));
	}
	delete name;
	deleteHtmlBuffer(val);
	return result;
}



class queue : public htmlObject{
   Selection *qbuf;
   htmlBuffer* type;
   htmlBuffer* domain;
   int que_id;
   int event;
   int priority;
   int handler;
   void initQueue();
   void setQue_id(int q){ que_id=q;}
   public:
   ~queue() { delete qbuf; deleteHtmlBuffer(type),deleteHtmlBuffer(domain);}
   queue(Buffer* name, htmlBuffer* type, htmlBuffer* domain,int eventh);
   htmlBuffer* getValue(htmlBuffer*);
   int putValue(Buffer*,htmlBuffer*);
   char getType() { return TYPQUEUE;}
   int getHandle(){return handler;}
   };

queue::queue(Buffer* name, htmlBuffer* qtype,htmlBuffer* dest,int eventh)
: htmlObject(name),type(qtype),domain(dest),que_id(0),event(eventh),priority(0),handler(eventh)
{
	initQueue();
}


int queue::putValue(Buffer* name,htmlBuffer* val)
{
	if(val==0 || name==0){
		delete name;
		delete val;
		return 0;
	}
	char *n=*name;
	int result=0;
	if(stricmp(n,"select")==0){
		delete qbuf;
		char *s=0;
		if (domain)
			s=*domain;
		qbuf=SelectFromQueue(*type,s,val);
		if(qbuf)
			setQue_id(qbuf->getNext(0,1));
		result=1;
	}else
		if(stricmp(n,"item")==0){
			htmlBuffer *tmp=htmlObject::getValue("type");
			if(tmp==0)
				tmp=new htmlBuffer("undefined");
			htmlObject::putValue("type",NULLVALUE);
			int rtime=0;
			char* rt=showValue("wait");
			if(rt && *rt){
				rtime=atoi(rt);
			}                
			htmlObject::putValue("wait",NULLVALUE);
			putIntoQueue(val,*type,tmp,priority,rtime,showValue("info"));
			htmlObject::putValue("info",NULLVALUE);
			val=0;
			result=1;
		}else
		if(stricmp(n,"queueId")==0){
			que_id=atoi(*val);
			result=1;
		}else
			if(stricmp(n,"position")==0){
				int pos=atoi(*val);
				if(pos && que_id){
					moveItem(que_id,pos);
				}
				result=1;
			}else
				if(stricmp(n,"priority")==0){
					priority=atoi(*val);
					result=1;
				}else
					if(handler && (stricmp(n,"status")==0)){
						eventSetStatus(handler,*val);
						result=1;
					}else
						if(handler && (stricmp(n,"size")==0)){
							eventSetSize(handler,atoi(*val));
							result=1;
						}else
							if(handler && (stricmp(n,"done")==0)){
								eventSetChunk(handler,atoi(*val));
								result=1;
							}else{
								return htmlObject::putValue(name,val);
							}
							delete val;
							delete name;
							return result;
}

void queue::initQueue()
{
	    char *s=0;
		if(domain)
			s=*domain;
		qbuf=getItemsFromQueue(*type,s);
		if(qbuf){
			setQue_id(qbuf->getNext(0,1));
		}
}

htmlBuffer* queue::getValue(htmlBuffer* name)
{
		char* x=*name;
		char tmp[16];
		if(stricmp(x,"resume")==0){
			eventResume(*type, domain,&event);;
			return 0;
		}else
		if(stricmp(x,"end")==0){
			ULONG n=getEventEndTime(*type, domain,&event);
			snprintf(tmp,16,"%lu",n);
			return new htmlBuffer(tmp);
		}else
			if(stricmp(x,"start")==0){
				ULONG n=getEventStartTime(*type, domain,&event);
				snprintf(tmp,16,"%lu",n);
				return new htmlBuffer(tmp);
			}else
				if(stricmp(x,"rate")==0){
					int n=getEventRate(*type, domain,&event);
					snprintf(tmp,16,"%d",n);
					return new htmlBuffer(tmp);
				}else
					if(stricmp(x,"oldrate")==0){
						return getEventOldRate(*type, domain,&event);
					}else
						if(stricmp(x,"active")==0){
							int n=getActiveEvent(*type, domain,&event);
							snprintf(tmp,16,"%d",n);
							return new htmlBuffer(tmp);
						}else
						if(stricmp(x,"progress")==0){
							int n=getEventProgress(*type, domain,&event);
							snprintf(tmp,16,"%d",n);
							return new htmlBuffer(tmp);
						}else
							if(stricmp(x,"size")==0){
								int n=getEventSize(*type, domain,&event);
								snprintf(tmp,16,"%d",n);
								return new htmlBuffer(tmp);
							}else
								if(stricmp(x,"status")==0){
									char* desc=getEventDesc(*type, domain,&event);
									if(desc && *desc)
										return new htmlBuffer(desc);
								}else
									if((stricmp(x,"deleteItem")==0) || (stricmp(x,"drop")==0)){
										if(que_id){
											abortEvent(*type, domain,&event,que_id);
											deleteQueueItem(que_id);
											delete qbuf;
											qbuf=0;
											setQue_id(0);
										}
									}else
										if(stricmp(x,"name")==0){
											return new htmlBuffer((char*)*type);
										}else
											if(stricmp(x,"types")==0){
												return getDomains(*type);
											}else
											if(stricmp(x,"type")==0){
												return getQueueType(que_id);
											}else
												if(type && stricmp(x,"queueId")==0){
													snprintf(tmp,16,"%d",que_id);
													return new htmlBuffer(tmp);
												}else
													if(stricmp(x,"selected")==0 || stricmp(x,"total")==0){
														if(qbuf==0)
															initQueue();
														if(qbuf){
															snprintf(tmp,16,"%d",qbuf->getTotal());
															return new htmlBuffer(tmp);
														}else{
															return new htmlBuffer("0");
														}
													}else
														if(stricmp(x,"next")==0){
															if(qbuf==0)
																initQueue();
															if(qbuf)
																setQue_id(qbuf->getNext(que_id,1));	
														}else
															if(stricmp(x,"item")==0){
																if(que_id){
																	setQue_id(que_id);
																	return(getQueueItem(que_id));
																}
															}else
																if(stricmp(x,"priority")==0){
																	if(que_id)
																		return(getQueuePriority(que_id));
																}else
																	if(stricmp(x,"info")==0){
																		if(que_id)
																			return(getQueueInfo(que_id));
																	}else
																		if(stricmp(x,"modify")==0){
																			if(que_id){
																				int rtime=-1;
																				char* rt=showValue("wait");
																				if(rt && *rt){
																					rtime=atoi(rt);
																				}                
																				htmlObject::putValue("wait",NULLVALUE);
																				modifyQueue(que_id,rtime,showValue("info"),priority);
																				priority=0;
																				htmlObject::putValue("info",NULLVALUE);
																			}
																		}
																		
	return 0;
}


class ipHost : public htmlObject{
	Buffer* hostName;
	Buffer *hpb;
	struct hostent *hp;
	char *lastErr;
	int port;
	Socket *s;
	int ok;
	htmlBuffer* dnServer;
	int connected;
public:
	~ipHost() { delete hostName,delete s;delete hpb;delete dnServer;}
	ipHost(Buffer* n, htmlBuffer* name);
	htmlBuffer* getValue(htmlBuffer*);
	int putValue(Buffer*,htmlBuffer*);
	char getType() { return TYPHOST;}
	void initHostEntry();
};

ipHost::ipHost(Buffer* n, htmlBuffer* name)
:htmlObject(n),hpb(0),hp(0),lastErr(0),port(0),s(0),ok(0),dnServer(0),connected(0)
{
	miner *m= new miner();
	hostName=0;
	if(m->mine(*name,"`*`:`*`")){
		hostName=m->getValueFinal(0);
		port=atoi(m->getValue(1));
	}else{
		hostName=*name;
	}
	delete m;
	delete name;
}

void ipHost::initHostEntry()
{
	if(hpb==0 && hostName!=0){
		if (dnServer==0){
			struct in_addr ip;
			ip.s_addr = inet_addr(*hostName);
			if (ip.s_addr != INADDR_NONE)
				hpb=gethostinfo((char*)&ip,1);
			if(hpb==0)
				hpb=gethostinfo(*hostName);
			if(hpb!=0)
				hp=(struct hostent*)((char*)(*hpb));
		}else{
			struct in_addr ip;
			ip.s_addr = inet_addr(*hostName);
			if (ip.s_addr != INADDR_NONE)
				hpb=gethostinfo((char*)&ip,1);
			if(hpb==0){
				int err;
				LinkedBuffer *s=getInetAddress(*hostName,&err,*dnServer);
				if(s){
					hpb=mkHostEntry(*hostName,s);
				}
			}
			if(hpb!=0)
				hp=(struct hostent*)((char*)(*hpb));
		}
	}
	ok=1;
}

int ipHost::putValue(Buffer*name,htmlBuffer* val)
{
	if(val==0 || name==0){
		delete name;
		delete val;
		return 0;
	}
	char *n=*name;
	if(stricmp(n,"port")==0){
		port=atoi(*val);
	}else
		if(stricmp(n,"dns")==0){
			dnServer=val;
			val=0;
		}else
		if(stricmp(n,"persistent")==0){
			setPersistent(stricmp(*val,NULLVALUE));
		}else
			if(stricmp(n,"send")==0){
				if(s==0){
					lastErr=0;
					s=new Socket();
				}
				if(hostName){
					if(connected || s->linkup(*hostName,port)){
						int n=val->getSize()-1;
						connected=1;
						if(n>0){
							if(s->Send(*val,n)!=n){
								lastErr="Error Sending Data";
							}
						}
					}else{
						lastErr=s->getError();
						connected=0;
					}
				}else{
					connected=0;
					lastErr="Invalid hostName or address";
				}
			}else{
				return htmlObject::putValue(name,val);
			}
	delete val;
	return 0;
}

/*
void  ipHost::getIP()
{
	if(hpb==0){
		struct in_addr ip;
		ip.s_addr=INADDR_NONE;
		miner *m=new miner();
		if(m->mine(*hostName,"`#~#`.`#~#`.`#~#`.`#~#`")){
			if((atoi(m->getValue(0)) < 256) && (atoi(m->getValue(1))<256) &&
				(atoi(m->getValue(2)) < 256) && (atoi(m->getValue(3)) < 256))
				ip.s_addr=inet_addr(*hostName);
		}
		delete m;
		if (ip.s_addr == INADDR_NONE) {
			// No IP address, so it must be a hostname, like ftp.wustl.edu. 
			hpb=gethostinfo(*hostName);
			if(hpb!=0){
				struct hostent *hp=(struct hostent*)((char*)*hpb);
				memcpy(&ip,hp->h_addr,hp->h_length);
			}
		}else{
			printf("here\r\n");
			hpb=gethostinfo((char*)&ip.s_addr,1);		
			printf("ok\r\n");
		}
		if(ip.s_addr != INADDR_NONE){
			char *addr=inet_ntoa(ip);
			ipAddr=new Buffer(addr,strlen(addr)+1);
		}
	}
}

*/

htmlBuffer* ipHost::getValue(htmlBuffer* name)
{		
		char* x=*name;
		if(stricmp(x,"recv")==0){
			if(s==0){
				lastErr=0;
				s=new Socket();
			}
			if(connected || s->linkup(*hostName,port) ){
				Buffer *rcvBuffer=new Buffer(1040);
				char *buff=*rcvBuffer;
				int n=s->Recv(buff,1024);
				if(n<=0){
					connected=0;
					lastErr="No data";
					delete rcvBuffer;
				}else{
					connected=1;
					lastErr=0;
					buff[n]=0;
					rcvBuffer->setSize(n+1);
					return new htmlBuffer(rcvBuffer);
				}
			}
		}else
		if(stricmp(x,"close")==0){
			delete s;
			s=0;
		}else
		if(stricmp(x,"address")==0){
				if(ok==0)
					initHostEntry();
				if(hp){
					struct in_addr ip;
					htmlBuffer *alist=0;
					htmlBuffer *al=0;
					for (char** curaddr=hp->h_addr_list; *curaddr != NULL; curaddr++) {
						memcpy(&ip, *curaddr, (size_t) hp->h_length);
						htmlBuffer *ipb=new htmlBuffer(inet_ntoa(ip));
						if(alist)
							al->next=ipb;
						else
							alist=ipb;
						al=ipb;
					}
					return alist;
				}
		}else
			if(stricmp(x,"mailserver")==0){
				htmlBuffer *rslt=0;
				htmlBuffer *last;
				if(hostName){
					int err;
					char *dns=0;
					if(dnServer)
						dns=*dnServer;
					LinkedBuffer* servers=getMailServer(*hostName,&err,dns);
					switch(err){
					case 1:lastErr="DNS error";break;
					case 3:lastErr="Bad Address";break;
					default:
						while(servers){
							htmlBuffer *c=new htmlBuffer((Buffer*)*servers);
							if(rslt){
								last->next=c;
							}else
								rslt=c;
							last=c;
							LinkedBuffer *x=servers;
							servers=x->next;
							delete x;
						}
					}
				}
				return rslt;
			}else
			if(stricmp(x,"PING")==0){
				if(ok==0){
					initHostEntry();
				}
				if(hp){
					int n=ping((char*)hp->h_addr);
					if(n!=-1){
						char ports[16];
						snprintf(ports,16,"%d",n);
						return new htmlBuffer(ports);
					}
				}
			}else
				if(stricmp(x,"hostname")==0){
							htmlBuffer *x;
							if(ok==0)
								initHostEntry();
							if(hp!=0){
								x=new htmlBuffer(hp->h_name);
							}else
								x=new htmlBuffer(*hostName);
							return x;
				}else
					if(lastErr && stricmp(x,"error")==0){
						return new htmlBuffer(lastErr);
					}else
					if(stricmp(x,"alias")==0){
						htmlBuffer *alias=0;
						htmlBuffer *l=0;
						if(ok==0)
							initHostEntry();
						if(hp!=0){
							for (char ** curaddr=hp->h_aliases; *curaddr != NULL; curaddr++) {
								htmlBuffer *m=new htmlBuffer(*curaddr);
								if(alias)
									l->next=m;
								else
									alias=m;
								l=m;
							}
						}
						return alias;;
					}else
						if(stricmp(x,"port")==0){
							char ports[16];
							snprintf(ports,16,"%d",port);
							return new htmlBuffer(ports);
						}
						return 0;
}



class loop : public htmlObject{
   int ptr;
   int loopCount;
   int maxCount;
   char running;
   public:
   loop(Buffer *n,int x) : htmlObject(n),ptr(x), loopCount(1),maxCount(0) ,running(TYPLOOP){};
   void stopRunning(){running=0;}
   ULONG getPos() {return ptr;}
   void incCount() { loopCount++;}
   int getCount() { return loopCount; }
   int continueLoop() { return (loopCount < maxCount); }
   void setMaxCount(int c) { maxCount = c; }
   htmlBuffer* getValue(htmlBuffer* );
   char getType() { return running;}
   };


htmlBuffer* loop::getValue(htmlBuffer* x)
{
  char tmp[16];
  if(stricmp(*x,"COUNT")==0 || stricmp(*x,"COUNTER")==0){
     snprintf(tmp,12,"0%d",loopCount);
     return (new htmlBuffer(tmp));
     }
  return 0;
}

class httpTime:public htmlObject, public Time{
static char* monthnames[12];
int offsetSec;
public:
httpTime(Buffer* name):htmlObject(name){offsetSec=0;}
htmlBuffer *getValue(htmlBuffer*);
char getType() { return TYPTIME;}
int putValue(Buffer*,htmlBuffer*);
int addValue(Buffer*,htmlBuffer*);
int subValue(Buffer*,htmlBuffer*);
void addTime(char*, int);
void offsetTime(int secs){offsetSec=secs;addSeconds(secs);}
};

char* httpTime::monthnames[]={"January","February","March","April","May","June","July","August","September","October","November","December"};



class htmlFile : public htmlObject{
   htmlBuffer *h;
   int offset,blockNo,blockSize;
   ByteStream *bs;
   inputStream *is;
   Buffer* lineBuff;
   int event;
   int locked;
public:
   htmlFile(Buffer *name,htmlBuffer *x,int,genericObject* objs,int);
   ~htmlFile() { delete h; delete bs; delete is; delete lineBuff;}
   htmlBuffer* getValue(htmlBuffer* s);
   int addValue(Buffer*,htmlBuffer*);
   int putValue(Buffer*,htmlBuffer*);
   File *getURL() { return h->getFile();}
   char getType() { return TYPFILE; }
   void lockf(int n) { locked=n;}
   int  islockf() { return locked;}
   };

int htmlFile::addValue(Buffer* name,htmlBuffer* val)
{
	if((stricmp(*name,"file")==0) || (stricmp(*name,"file(01)")==0)){
		File *fn=h->getFile();
		if(fn!=0){
			if(fn->exists()==0)
				fn->create();
			File *f=val->getFile();
			fn->seekEND();
			if(f!=0 ){
				f->seekTo(0);
				int n;
				Buffer *b=new Buffer(BFSIZE);
				char *buff=*b;
				do{
					n=f->read(buff,BFSIZE);
					n=fn->write(buff,n);
				}while(n==BFSIZE);
				fn->setLastWriteTime(f->lastWriteTime());
				delete b;
				f->close();
			}else
				fn->write(*val,val->getSize()-1);
			fn->close();
		}
	}
	deleteHtmlBuffer(val);
	delete name;
	return 1;
}

int htmlFile::putValue(Buffer*name,htmlBuffer* val)
{
   if(val==0 || name==0){
      delete name;
      delete val;
      return 0;
      }
   char *n=*name;
   if(stricmp(n,"offset")==0){
	   offset=atoi(*val);
   }else
   if(stricmp(n,"blockSize")==0){
	   blockSize=atoi(*val);
   }else
   if(stricmp(n,"blockNo")==0){
      blockNo=atoi(*val);
   }else
   if(stricmp(n,"block")==0){
      File *fd=h->getFile();
	  if(fd->exists()==0)
		  fd->create();
      if(fd!=0){
         fd->seekTo(offset+blockSize*blockNo);
		 if(blockSize>0 && val->getSize()>blockSize)
			 fd->write(*val,blockSize);
		 else
			 fd->write(*val,val->getSize()-1);
         fd->close();
	  }
   }else
   if(stricmp(n,"newfilename")==0){
       File *f=val->getFile();
       if(f==0){
		   File *fn=h->getFile();
		   if(fn){
			   char *p=*val;
			   int i=strlen(p)-1;
			   for(;i>0;--i){
				   if(p[i]==FSLASH){
					   i++;
					   break;
				   }
			   }
			   if(fn->rename(p)){
				   fn->setName(p+i);
			   }
		   }	  
       }
   }else
   if(stricmp(n,"filename")==0){
       File *f=val->getFile();
       if(f==0){
          File *fn=h->getFile();
		  if(fn)
		   fn->setName(*val);
       }
   }else
	   if(stricmp(n,"file")==0){
		   File *fn=h->getFile();
		   if(fn!=0){
			   if (fn->exists()){
				   fn->replace();
			   }else
				   fn->create();
			   File *f=val->getFile();
			   if(f!=0 ){
				   f->seekTo(0);
				   int n;
				   Buffer *b=new Buffer(BFSIZE);
				   char *buff=*b;
				   do{
					   n=f->read(buff,BFSIZE);
					   n=fn->write(buff,n);
				   }while(n==BFSIZE);
				   fn->setLastWriteTime(f->lastWriteTime());
				   delete b;
				   f->close();
			   }else
				   fn->write(*val,val->getSize()-1);
			   fn->close();
		   }
	   }else
		   if(stricmp(n,"attribute")==0){
			   File *fd=h->getFile();
			   if(fd){
				   if(stricmp(*val,"new")==0)
					   fd->setFileArchive(1);
				   else
					   if(stricmp(*val,"old")==0)
						   fd->setFileArchive(0);
			   }
		}else
  if(stricmp(n,"time")==0){
     ULONG n=atol(*val);
     if(n!=0){
        File *fd=h->getFile();
        if(fd)
           fd->setLastWriteTime(n);
        }
     }else
     if(stricmp(n,"persistent")==0){
      setPersistent(stricmp(*val,NULLVALUE));
     }
  delete name;
  deleteHtmlBuffer(val);
  return 0;
}


htmlFile::htmlFile(Buffer *name,htmlBuffer *x,int eventh,genericObject* objs,int instance)
  : htmlObject(name), h(x),offset(0),blockNo(0),blockSize(0),bs(0),is(0),lineBuff(0),event(eventh),locked(0)
{
	File *fd=0;
	if(h && h->isBuff()){
		char *c=*h;
		int i=strlen(c)-1;
		for(;i>0 && c[i]!=':' && c[i]!= SLASH && c[i]!= FSLASH ;--i);
		if(i==0){
			fd=new vFile(*h);
		}else{
			if((strnicmp(c,"http:",5)==0) || (strnicmp(c,"ftp:",3)==0)){
				fd=getNetWorkFile(c,objs,instance,event);
				if(fd==0){
					fd=new vFile("404.html");
				}
			}
		}
		if(fd==0){
			fd=new File(c);
			if (fd->exists()==0){
				delete fd;
				fd=new RealFile(c);
			}
		}
		delete h;
		h=new htmlBuffer(fd);
	}
}


htmlBuffer* htmlFile::getValue(htmlBuffer* bname)
{
	char* name=*bname;
	if(h){
		File *fd=h->getFile();
		if(fd!=0){
			if(stricmp(name,"getline")==0){
				if(is == 0){
					goto nextLine;
				}
				if(lineBuff==0)
					return 0;
				return new htmlBuffer(new Buffer(*lineBuff,lineBuff->getSize()));
			}else
			if(stricmp(name,"nextline")==0){
				if(is == 0){
nextLine:
					fd->open();
					bs=new fileStream(fd);
					is=new inputStream(bs);
				}
				Buffer *tbuf=new Buffer(0x40000);
				int n=is->GetLine(*tbuf,0x40000);
				htmlBuffer* r=0;
				delete lineBuff;
				lineBuff=0;
				if(n>0){
					if(stricmp(name,"getline")==0)
						r=new htmlBuffer(new Buffer(*tbuf,n));
					else
						r=new htmlBuffer("ok");
					lineBuff=new Buffer(*tbuf,n);
				}
				delete tbuf;
				return r;
			}else
				if(stricmp(name,"block")==0){
					Buffer *b;
					if(blockSize>0)
						b=new Buffer(blockSize+1);
					else
						b=new Buffer(0x10001);
					if(blockSize>0 && blockNo>0)
						fd->seekTo(offset+blockNo*blockSize);
					else
						fd->seekTo(offset);
					int n=fd->read(*b,b->getSize()-1);
					if(n>0){
						fd->close();
						*(((char*)*b)+n)='\0';
						if(n<b->getSize())
							b->setSize(n+1);
						return new htmlBuffer(b);
					}
					fd->close();
					delete b;
					return 0;
				}else
				if((stricmp(name,"replace")==0)){
					if(h){
						File *fd=h->getFile();
						if((fd!=0) && (fd->isReal()==1)){
							delete bs;
							delete is;
							bs=0;
							is=0;
							RealFile *f=new RealFile(fd->getName());
							delete h;
							if(f->exists()==0)
								f->create();
							h=new htmlBuffer(f);
						}
					}
				}else
				if((stricmp(name,"file")==0) || (stricmp(name,"content")==0)){
					return(new htmlBuffer(fd));
				}else
						if(stricmp(name,"filename")==0){
							return(new htmlBuffer(fd->getRealName()));
						}else
							if(stricmp(name,"extension")==0 || stricmp(name,"extention")==0){
								return(new htmlBuffer(fd->getExt()));
							}else
								if(stricmp(name,"size")==0){
									char tmp[16];
									snprintf(tmp,16,"%ld",fd->size());
									return(new htmlBuffer(tmp));
								}else
									if(stricmp(name,"time")==0){
										ULONG t=fd->lastWriteTime();
										char tmp[16];
										snprintf(tmp,16,"%ld",t);
										return(new htmlBuffer(tmp));
									}else
									if(stricmp(name,"crc")==0){
										char tmp[16];
										snprintf(tmp,16,"%lu",fd->getCrc());
										return(new htmlBuffer(tmp));
									}else
									if(stricmp(name,"scramble")==0){
										encryptFile(fd,1);
									}else
									if(stricmp(name,"unscramble")==0){
										encryptFile(fd,0);
									}


		}
	}
	return 0;
}

htmlBuffer* httpTime::getValue(htmlBuffer* bname)
{
char* name=*bname;
Buffer *r=0;
char s[12];
if(stricmp(name,"dd")==0){
 snprintf(s,3,"%02d",getDate());
 r = new Buffer(s,3);
 }else
if(stricmp(name,"mm")==0){
 snprintf(s,3,"%02d",getMonth());
 r = new Buffer(s,3);
 }else
if(stricmp(name,"yy")==0){
 snprintf(s,3,"%02d",getYear()%100);
 r = new Buffer(s,3);
 }else
if(stricmp(name,"date")==0){
 r = getDateString();
 }else
if(stricmp(name,"day")==0){
 r= getDayString();
}else
if(stricmp(name,"hour")==0){
 r= getHourString();
}else
if(stricmp(name,"minute")==0){
 r= getMinuteString();
}else
if(stricmp(name,"second")==0){
 r= getSecondString();
}else
if(stricmp(name,"year")==0){
 r= getYearString();
}else
if(stricmp(name,"month")==0){
 r= getMonthString();
}else
if(stricmp(name,"time")==0){
 snprintf(s,12,"%lu",(ULONG)*this);
 r = new Buffer(s,strlen(s)+1);
}else
if(stricmp(name,"rfctime")==0){
 char * s=rfcFormat(offsetSec);
 r=new Buffer(s,strlen(s)+1);
}else
if(stricmp(name,"localtime")==0){
 char *s=local();
 r=new Buffer(s,strlen(s)+1);
}else
if(stricmp(name,"set")==0){
 SetDateTime((ULONG)*this);
}else
if(stricmp(name,"timezone")==0){
 snprintf(s,12,"%d",initTimeZone());
 r = new Buffer(s,strlen(s)+1);
}
if(r)
   return(new htmlBuffer(r));
return 0;
}

int httpTime::addValue(Buffer* nameBuff, htmlBuffer* val)
{
if(val && nameBuff){
   addTime(*nameBuff,atoi(*val));
   }
deleteHtmlBuffer(val);
delete nameBuff;
return 0;
}

int httpTime::subValue(Buffer* nameBuff, htmlBuffer* val)
{
if(val && nameBuff){
   addTime(*nameBuff,atoi(*val)*-1);
   }
deleteHtmlBuffer(val);
delete nameBuff;
return 0;
}

void httpTime::addTime(char* name, int v)
{
if(stricmp(name,"date")==0){
 addSeconds(v*3600*24);
 }else
  if(stricmp(name,"week")==0){
     addSeconds(v*7*24*3600);
     }else
      if(stricmp(name,"hour")==0){
         addSeconds(3600*v);
         }else
          if(stricmp(name,"minute")==0){
             addSeconds(v*60);
             }else
              if(stricmp(name,"second")==0){
                 addSeconds(v);
                 }else
                   if(stricmp(name,"year")==0){
                      addYears(v);
                      }else
                       if(stricmp(name,"month")==0){
                          addMonths(v);
                          }

}


int httpTime::putValue(Buffer* n,htmlBuffer* v)
{
	if(n && v){
      if(stricmp(*n,"time")==0){
         SetTime(atoi(*v));
      }else
      if(stricmp(*n,"rfctime")==0){
         SetTime(convertRFCformat(*v));
      }else
       if(stricmp(*n,"month")==0){
         int j=atoi(*v);
         if(j==0){
            for(;j<12;++j)
               if(strnicmp(*v,monthnames[j],3)==0){
                  SetMonth(j);
                  break;
                  }
            }else{
               if(j<13)
                  SetMonth(j-1);
               }
      }else
      if(stricmp(*n,"Second")==0){
         int j=atoi(*v);
         SetSecond(j);
      }else
      if(stricmp(*n,"Minute")==0){
         int j=atoi(*v);
         SetMinute(j);
      }else
      if(stricmp(*n,"hour")==0){
         int j=atoi(*v);
         SetHour(j);
      }else
      if(stricmp(*n,"year")==0){
         int j=atoi(*v);
         if(j!=0){
               SetYear(j);
               }
      }else
      if(stricmp(*n,"date")==0){
         int j=atoi(*v);
         if(j!=0){
               SetDate(j);
               }
      }else
        if(stricmp(*n,"persistent")==0){
          setPersistent(stricmp(*v,NULLVALUE));
       }
    }
    delete v;
    delete n;
    return 0;
}


class htmlFolder : public htmlObject{
   int total;
   int plen;
   char path[PATHMAX];
   Buffer *filespec;
   finder *ffinder;
   ULONG datefrom;
   ULONG dateto;
   int skipto;
   int minsize;
   int maxsize;
   int count;
   enum TYPES{ALLTYPE=0,DIRTYPE=1,FILETYPE=2,FILENEW=3};
   TYPES type;
   int findNext();
   void getFinder();
   int replace;
   Buffer *currentFile;
   int sortby;
   int sortorder;
   int getCurrentFile();
   void newFinder(){ delete ffinder;ffinder=0;}
   public:
   htmlFolder(Buffer *,htmlBuffer* );
   ~htmlFolder() { delete filespec; delete ffinder;delete currentFile;}
   htmlBuffer* getValue(htmlBuffer*);
   int putValue(Buffer*, htmlBuffer*);
   char getType() { return TYPFOLDER;}
   };


htmlFolder::htmlFolder(Buffer *name, htmlBuffer* p)
 : htmlObject(name), total(0),filespec(new Buffer("*",2)),ffinder(0),
datefrom(0),dateto(0), skipto(1),minsize(0),maxsize(0),type(ALLTYPE),replace(0),currentFile(0),sortby(0),sortorder(0)
{
	if(p){
		strncpy(path,*p,PATHMAX);
		char* tmp=path;
		plen=strlen(tmp);
		for (;*tmp!=0 ;tmp++ ) {
			if(*tmp==SLASH)
				*tmp=FSLASH;
		}
		if(plen>1){
			if(*--tmp==FSLASH){
				*tmp=0;
				plen--;
			}
		}
		delete p;
	}
}

int htmlFolder::getCurrentFile()
{
	if(currentFile){
		int r=0;
		int cnt=count;
		if(ffinder->isValid()!=0){
			do{
				if(filenamecmp(*currentFile,ffinder->getName())==0){
					r=1;
					break;
				}
			}while(findNext());
		}
		if(r==0){
			ffinder->rewind(0);
			if((count=ffinder->isValid())!=0){
				do{
					if(filenamecmp(*currentFile,ffinder->getName())==0){
						r=1;
						break;
					}
				}while(count<cnt && findNext());
			}
		}
		delete currentFile;
		currentFile=0;
		return r;
	}else
		return(ffinder->isValid());
}


int htmlFolder::findNext()
{
	if(ffinder->find()){
		count++;
		return 1;
	}
    return 0;
}

void htmlFolder::getFinder()
{
	if(ffinder==0){
		ffinder=new finder(path,minsize,maxsize,datefrom,dateto);
		if(type==FILETYPE)
			count=ffinder->findFile(*filespec);
		else{
			if(type==DIRTYPE){
				count=ffinder->findDirectory(*filespec);
			}
			else
				if(type==ALLTYPE){
					count=ffinder->findAll(*filespec);
				}
				else
					if(type==FILENEW){
						count=ffinder->findNew(*filespec);
					}
		}
	}
	if(sortby!=0)
		ffinder->sortFiles(sortby,sortorder);
	while((count<skipto) && findNext());
	skipto=1;
}


htmlBuffer* htmlFolder::getValue(htmlBuffer* name)
{ 
	char b[12];
	htmlBuffer *result=0;
	char* n=*name;
	if(stricmp(n,"replace")==0){
	  replace=1;
    }else
	if(stricmp(n,"count")==0){
      snprintf(b,7,"%d",count);
      result=new htmlBuffer(b);
    }else
	if(stricmp(n,"path")==0){
	  char *tmp=path;
	  if(tmp[plen]==0)
		  result= new htmlBuffer("/");
	  else{
		  result=new htmlBuffer(tmp+plen);
		  for(tmp=*result;*tmp!=0;tmp++){
			  if(*tmp==FSLASH)
				  *tmp='/';
		  }
	  }
    }else
	if((stricmp(n,"folder")==0)){
			char* tmp=path;
			int n;
			if((n=strlen(tmp))>0){
				for(int i=n-1;i>=plen;--i)
					if(tmp[i]==FSLASH){
						result=new htmlBuffer(tmp+i+1);
						break;
					}
			}
	}else{
	if(ffinder==0){
		getFinder();
		if(stricmp(n,"findNext")==0)
			return 0;
	}
	if(stricmp(n,"findfirst")==0){
		ffinder->rewind(0);
		count=ffinder->isValid();
	}else
	if(stricmp(n,"desc")==0 || stricmp(n,"asc")==0){
		if(sortby==0)
			sortby=SORTBYNAME;
		if(stricmp(n,"asc")==0)
			sortorder=0;
		else
			sortorder=1;
		getFinder();
	}else
	if((stricmp(n,"deleteFolder")==0)){
			char* tmp=path;
			int n;
			int success=0;
			if((n=strlen(tmp))>0){
				for(int i=n-1;i>=plen;--i){
					if(tmp[i]==FSLASH){
						DirectoryDelete(tmp,success);                                        
						if(success){
							tmp[i]=0;
						}
						break;
					}
				}
			}
			if(success){
				newFinder();
			}
	}else
	if((stricmp(n,"deleteFile")==0)){
		if(getCurrentFile()){
			if(ffinder->isDirectory()==0){
				char *dfile=ffinder->getFullName();
				if(dfile!=0){
					int success;
					FileDelete(dfile,success);
					if(success){
						ffinder->remove();
						if(findNext()==0)
							count--;
					}
				}
			}
		}
	}else
	if(stricmp(n,"exists")==0 || stricmp(n,"ok")==0){
		if(ffinder->ok())
			return new htmlBuffer("yes");
		return 0;
	}else
	if(stricmp(n,"findNext")==0){
		 getCurrentFile();
		 findNext();
	}else
		if(stricmp(n,"nextfile")==0){
			getCurrentFile();
			while(findNext() && ffinder->isDirectory());
	}else
		if(stricmp(n,"nextfolder")==0){
			getCurrentFile();
			while(findNext() && (ffinder->isDirectory()==0));
		}else
			if(stricmp(n,"total")==0){
				if(sortby==0)
					sortby=SORTBYNAME;
				ffinder->sortFiles(sortby,sortorder);
				count=ffinder->isValid();
				int cnt=count;
				while(findNext())
					cnt++;
				snprintf(b,12,"%d",cnt);
				ffinder->rewind(0);
                return new htmlBuffer(b);
			}else{
			if(getCurrentFile()){
				if(stricmp(n,"size")==0){
					snprintf(b,12,"%lu",ffinder->getSize());
					result=new htmlBuffer(b);
				}else
					if((stricmp(n,"time")==0  || stricmp(n,"date")==0)){
						ULONG t=ffinder->lastWriteTime();
						snprintf(b,12,"%lu",t);
						result=new htmlBuffer(b);
					}else
						if(stricmp(n,"type")==0){
							if(ffinder->isDirectory())
								result=new htmlBuffer("folder");
							else
								result=new htmlBuffer("file");
						}else
							if(stricmp(n,"extension")==0 || stricmp(n,"extention")==0){
								result = new htmlBuffer(ffinder->getExtension());
							}else
								if(stricmp(n,"fullname")==0){
									result = new htmlBuffer(ffinder->getFullName());
								}else
									if(stricmp(n,"file")==0){
										char* tmp=ffinder->getFullName();
										File *f=new File(tmp);
										f->changeName(tmp,1);
										result=new htmlBuffer(f);
									}else
										if(stricmp(n,"filename")==0){
											result = new htmlBuffer(ffinder->getName());
										}
			}
		}
	}
	return result;
}


int htmlFolder::putValue(Buffer* name, htmlBuffer* val)
{ 
	if(val==0 || name==0){
		deleteHtmlBuffer(val);
		delete name;
		return 0;
	}
	char pb[512];
	int over=0;
	char *n=*name;
	if(stricmp(n,"filename")==0){
		delete currentFile;
		currentFile=*val;
		delete name;
		deleteHtmlBuffer(val);
		return 0; 
	}
	if(stricmp(n,"sortby")==0){
		if(stricmp(*val,"filename")==0){
			sortby=SORTBYNAME;
		}else
		if(stricmp(*val,"size")==0){
			sortby=SORTBYSIZE;
		}else
		if(stricmp(*val,"date")==0){
			sortby=SORTBYDATE;
		}
		getFinder();
	}else
    if(stricmp(n,"persistent")==0){
		setPersistent(stricmp(*val,NULLVALUE));
	}else
	if(stricmp(n,"filespec")==0){
		delete filespec;
		filespec=*val;
		over=1;
	}else
		if(stricmp(n,"folder")==0){
			int n;
			if(stricmp(*val,".")){
				char* valc=*val;
				for(n=0;valc[n]!=0;++n)
					if(valc[n]==SLASH)
						valc[n]=FSLASH;
				if(*valc==FSLASH){
					if(valc[n-1]==FSLASH){
						n--;
						valc[n]=0;
					}
					n+=plen;
					if(n>plen)
						strncpy(path+plen,valc,PATHMAX-plen);
					over=1;
				}else{
					if(stricmp(valc,"..")==0){
						char* tmp=path;
						if((n=strlen(tmp))>0){
							for(int i=n-1;i>=plen;--i)
								if(tmp[i]==FSLASH){
									tmp[i++]=0;
									newFinder();
									getFinder();
									int y=0;
									do{
										if(ffinder->isDirectory() && (filenamecmp(tmp+i,ffinder->getName())==0)){
											break;
										}
									}while(findNext());
									break;
								}
								
						}
					}else{
						n=strlen(path);
						path[n++]=FSLASH;
						strncpy(path+n,valc,PATHMAX-n);
						over=1;
					}
				}
			}
		}else
			if(stricmp(n,"type")==0){
				if(stricmp(*val,"folder")==0)
					type=DIRTYPE;
				else
					if(stricmp(*val,"file")==0)
						type=FILETYPE;
					else
						if(stricmp(*val,"all")==0)
							type=ALLTYPE;
					else
						if(stricmp(*val,"NEW")==0)
							type=FILENEW;
						over=1;
			}else{
				if(stricmp(n,"datefrom")==0 || stricmp(n,"NT")==0){
					datefrom=atoi(*val);
					over=1;
				}else
					if(stricmp(n,"dateto")==0 || stricmp(n,"OT")==0){
						dateto=atoi(*val);
						over=1;
					}else
						if(stricmp(n,"minsize")==0 || stricmp(n,"BT")==0){
							minsize=atoi(*val);
							over=1;
						}else
							if(stricmp(n,"maxsize")==0 || stricmp(n,"ST")==0){
								maxsize=atoi(*val);
								over=1;
							}else
								if(stricmp(n,"count")==0){
									skipto=atoi(*val);
									if (skipto>count)
										over=1;
								}

			}
			if(over){
				newFinder();
				delete name;
				deleteHtmlBuffer(val);
				return 1;
			}
			getFinder();
			if(ffinder->ok()){
				if((stricmp(n,"newfilename")==0) && getCurrentFile()){
					File *fn=new File(ffinder->getFullName());
					if(fn->rename(*val)){
						newFinder();
						delete currentFile;
						currentFile=*val;
					}
					delete fn;
				}else
				if(stricmp(n,"newfolder")==0){
					if(path){
						snprintf(pb,512,"%s%c%s",ffinder->getPath(),FSLASH,(char*)*val);
						mkDirectory(pb);
						delete currentFile;
						currentFile=*val;
						newFinder();
					}
				}else
					if(stricmp(n,"file")==0){
						File *f=val->getFile();
						File *delf=0;
						if(f==0){
							f=new File(*val);
							if(f->exists()==0){
								delete f;
								f=0;
							}else
								delf=f;
						}
						if(f){
							Buffer *b=new Buffer(BFSIZE);
							f->seekTo(0);
							Buffer *v=0;
							char *buffer=*b;
							int newfinder=0;
							if(ffinder->ok()){
								strcpy(buffer,ffinder->getPath());
								int l=strlen(buffer);
								buffer[l++]=FSLASH;
								strcpy(buffer+l,f->getRealName());
								RealFile *r=new RealFile(buffer);
								if(f->exists()){
									if(r->exists()){
										if(replace)
											r->replace();
										else{
											r->createUnique();
											newfinder=1;
										}
									}else{
										r->create();
										newfinder=1;
									}
									v=new Buffer(r->filenameOnly()+1);
									r->filenameOnly(*v);
								}else{
									v=new Buffer(f->filenameOnly()+1);
									f->filenameOnly(*v);
								}
								int nread;
								do{
									nread=f->read(buffer,BFSIZE);
									nread=r->write(buffer,nread);
								}while(nread==BFSIZE);
								r->setLastWriteTime(f->lastWriteTime());
								f->close();
								r->close();
								delete r;
							}
							delete delf;
							delete b;
							if (v!=0){
								if((currentFile==0) || strcmp(*currentFile,*v)){
									delete currentFile;
									currentFile=v;
									if(newfinder)
										newFinder();
								}else
									delete v;
							}
						}
					}
			}
			delete name;
			deleteHtmlBuffer(val);
			return 0;
}




extern DataBaseManager *dbms;

class httpUser: public htmlObject{
   int cid;
   int uid;
   int admin;
   int thisUser;
   Table *data;
   int selected;
   Selection *selection;
   char server[128];
   char code[16];
   public:
   int authorised() { return (admin || (thisUser==uid)); }
   httpUser(Buffer *,int,int);
   ~httpUser() { dbms->closeDB(cid); delete selection;}
   htmlBuffer* getValue(htmlBuffer*);
   int putValue(Buffer*,htmlBuffer*);
   char getType() { return TYPUSER;}
   };


httpUser::httpUser(Buffer *name, int authority,int cu)
: htmlObject(name),cid(0),uid(cu),admin(authority),thisUser(cu),data(0),selected(0),selection(0)
{
server[0]=0;
code[0]=0;
cid = dbms->openDB(caravan);
if(cid!=0)
 if((data=dbms->selectTable(cid,"users"))!=0){
   if(data->exists()){
      selection=data->getSelection(cid,new Buffer("order by username",21),0);
	  selected=selection->getTotal();
   }else
     data=0;
  }
}


int httpUser::putValue(Buffer* name, htmlBuffer* val)
{
    if(val==0 || name==0 || data==0){
		delete val;
		delete name;
		return 0;
	}
	char *n=*name;
	if(stricmp(n,"uid")==0){
		uid=atoi(*val);
		if(data->exists(uid)==0){
			uid=0;
			if (admin && selection) {
				uid=selection->getNext(0,1);
			} 
		}
		delete name;
		delete val;
		return 1;
	}else
	if(stricmp(n,"SendTo")==0){
		strncpy(server,*val,128);
		delete val;
		delete name;
		return 1;
	}else
	if(stricmp(n,"sender")==0){
		strncpy(code,*val,16);
		delete val;
		delete name;
		return 1;
	}else{
		if(stricmp(n,sUSERID)==0){
			uid=data->getKeyRecord(sUSERID,*val);
			if(uid>0){
				delete name;
				delete val;
				return 1;
			}
		}
		if(authorised()){
			if((stricmp(n,"moreinfo")==0) || (stricmp(n,"link")==0)){
				delete name;
				name=new Buffer("moreinfo",9);
				n=*name;
				if(atoi(*val)){
					if(uid>0){
						if(val && atoi(*val)){
							htmlObject *v=new htmlObject();
							v->putValue(name,val);
							data->updateRecord(v,uid);
							delete v;
							return 1;
						}
					}else{
						htmlObject::putValue(name,val);
						return 1;
					}
				}
			}else
				if((stricmp(n,"username")==0) || (strnicmp(n,sDOMAIN,DOMAINl-1)==0) || (stricmp(n,"userid")==0) || (stricmp(n,sPSWD)==0) || (stricmp(n,sSERVER)==0) || (stricmp(n,FTPHOME)==0) || (stricmp(n,"userinfo")==0)){
					if(uid>0){
						htmlObject *v=new htmlObject();
						htmlBuffer* vo=data->getFieldValue(uid,sDOMAIN);
						v->putValue(new Buffer(sDOMAIN,DOMAINl),vo);
						if(strnicmp(n,sDOMAIN,DOMAINl-1)==0){
							if(stricmp(*val,NULLVALUE)){
								v->putValue(sDELIM,"|");
								char* tmpn="_tmp";
								v->putValue(new Buffer(tmpn,5),val);
								vo=v->getValue(sDOMAIN);
								htmlBuffer* vl=v->getValue(tmpn);
								htmlBuffer* zl=0;
								htmlBuffer* z=0;
								while(vl){
									htmlBuffer* vp=vo;
									while(vp){
										if(stricmp(*vp,*vl)==0)
											break;
										vp=vp->next;
									}
									htmlBuffer* tl=vl->next;
									if(vp==0){
										if(z==0)
											z=vl;
										else
											zl->next=vl;
										zl=vl;
									}else
										delete vl;
									vl=tl;
								}
								if(z){
									zl->next=0;
									v->putValue(name,z);
								}
							}else{
								v->putValue(name,val);
								v->putValue(sDOMAIN,"");
							}
						}else{
							/*
							if((stricmp(n,sPSWD)==0) && (thisUser!=uid)){
//								deleteHtmlBuffer(val);
//								val=new htmlBuffer(sPSWD);
							}
*/
							v->putValue(name,val);
						}
						data->updateRecord(v,uid,1);
						delete v;
						return 1;
					}else{
						if(admin){
							int resetDelim=0;
							if(stricmp(n,"userinfo")==0){
								File *f=val->getFile();
								if(f){
									encryptFile(f,0);
									f->seekTo(0);
									LZW *l=new LZW();
									File* fi;
									*code=0;
									if((fi=l->expand(f))!=0){
										htmlObject *o = new htmlObject();
										fileStream *fs=new fileStream(fi);
										fi->seekTo(0);
										inputStream *in=new inputStream(fs);
										o->readForm(in);
										delete in;
										delete fs;
										delete fi;
										char *s=o->showValue("sender");
										if(s){
											o->putValue("_from_",s);
											strncpy(code,s,16);
										}
										s=o->showValue(sUSERID);
										if((s!=0) && (*s!=0)){
											uid=data->getKeyRecord(sUSERID,s);
											if(uid>0){
												data->updateRecord(o,uid,1);
											}else{
												o->putValue("domain","update");
												if(o->showValue("username") && o->showValue(sUSERID))
													uid=data->insertRow(o,1);
											}
										}
										delete o;
									}
									delete l;
								}
								delete name;
								delete val;
								return 0;
							}else
							if(stricmp(n,sDOMAIN)==0){
								resetDelim=1;
								htmlObject::putValue(new Buffer(sDELIM,DELIMl),new htmlBuffer("|"));
							}
							htmlObject::putValue(name,val);
							if(resetDelim)
								htmlObject::putValue(new Buffer(sDELIM,DELIMl),new htmlBuffer(NULLVALUE));
							return 1;
						}
					}
				}
		}
	}
	delete name;
	delete val;
	return 0;
}

int sendUserInfo(int uid,char* server,char *sender);


htmlBuffer* httpUser::getValue(htmlBuffer *name)
{
	if(data==0 || name==0)
		return 0;
	char*n=*name;
    if(stricmp(n,sPSWD)==0)
     return 0;
    else
    if(admin && (stricmp(n,"add")==0)){
         if(showValue("username") && showValue("userid") && showValue("domain"))
             uid=data->insertRow(this,1);
    return 0;   
    }else
    if(stricmp(n,"total")==0){
     char b[12];
     snprintf(b,12,"%d",selected);
     return(new htmlBuffer(b));
    }else
    if(stricmp(n,"uid")==0){
     char b[12];
     snprintf(b,12,"%d",uid);
     return(new htmlBuffer(b));
    }else
    if(stricmp(n,"prev")==0){
	   if(selection)
        uid=selection->getNext(uid,-1);
       return 0;
   }else
   if(stricmp(n,"next")==0){
    if(selection)
     uid=selection->getNext(uid,1);
    return(0);
   }else
	   if(uid>0){
         if(admin){
			 if(stricmp(n,"delete")==0){
              data->deleteRecord(uid);
			  uid=0;
			  return 0;
			 }else
			 if(stricmp(n,"send")==0){
				 if(*server && *code){
					 char tmp[16];
					 snprintf(tmp,16,"%d",sendUserInfo(uid,server,code));
					 return(new htmlBuffer(tmp));
				 }
				 return 0;
			 }else
				 if(stricmp(n,"sender")==0){
					 if(*code){
						 return new htmlBuffer(code);
					 }
				 }
		 }
         if(authorised()){
          if(stricmp(n,"link")==0)
            n="moreinfo";
          return(data->getFieldValue(uid,n));
		 }
	   }
return 0;
}

class htmlTable: public htmlObject{
   int selected;
   int recordNo;
   int cid;
   Table *data;
   Selection *selection;
   Selection *savedSelection;
   int savedRecordNo;
   int savedSelected;
   int order;
   htmlBuffer *fieldList;
   Runnable *thread;
   char uid[32];
   public:
   void deleteSelection(){ if (selection!=savedSelection) delete selection;selection=0;selected=0;recordNo=0;};
   void select(Buffer* query,int add);
   htmlTable(Buffer* objName,char* dbname,char* tbname,char *id,Runnable*);
   ~htmlTable() { deleteSelection(); delete savedSelection; delete fieldList; dbms->closeDB(cid); }
   int createdOK() { return(data!=0);}
   htmlBuffer* getValue(htmlBuffer*);
   int putValue(Buffer*,htmlBuffer*);
   int addValue(Buffer*,htmlBuffer*);
   int subValue(Buffer*,htmlBuffer*);
   int divValue(Buffer*,htmlBuffer*);
   int modValue(Buffer*,htmlBuffer*);
   int mulValue(Buffer*,htmlBuffer*);
   char getType() { return TYPTABLE;}
   void executeQuery(Buffer*,genericObject*f=0,int add=0);
   htmlBuffer* getMax(char* field,int order);
};


htmlTable::htmlTable(Buffer* objName,char* dbname,char* tbname,char* id,Runnable* thisthread)
:htmlObject(objName), selected(0) , recordNo(0), data(0),selection(0),savedSelection(0),savedSelected(0),order(1),fieldList(0),thread(thisthread)
{
	if(id){
		strncpy(uid,id,30);
	}else
		uid[0]=0;
	cid = dbms->openDB(dbname);
	if(cid!=0){
		if((data=dbms->selectTable(cid,tbname))!=0){
			if(data->exists()){
				selected=data->getTotal();
				recordNo=(*data)[1];
			}else{
				data=0;
			}
		}
	}
}



int htmlTable::putValue(Buffer* n,htmlBuffer* v)
{
	if(v==0 || n==0){
		delete v;
		delete n;
		return 0;
	}
	if(stricmp(*n,"persistent")==0){
		setPersistent(stricmp(*v,NULLVALUE));
		delete v;
		delete n;
		return 1;
	}
	if(stricmp(*n,"tableinfo")==0){
		xmlObject *tinfo=new xmlObject(0,v);
		htmlBuffer *val=tinfo->getValue("_error");
		if(val==0){
			val=tinfo->getValue("_name");	 
			if(val && stricmp(*val,"Table")==0){
				htmlBuffer *db=tinfo->getValue("_attribute(db)");
				if(db){
					htmlBuffer* table=tinfo->getValue("_attribute(table)");
					if (table){
						dbms->closeDB(cid);
						cid=dbms->openDB(*db);
						if(cid==0){
							dbms->createDB(*db);
							cid=dbms->openDB(*db);
						}
						if(cid){
							data=dbms->selectTable(cid,*table);
							data->makeTable(tinfo);
						}
						delete table;
					}
					delete db;
				}
			}
		}
		delete val;
		delete tinfo;
		delete n;
		delete v;
		return 0;
	}
	if(data==0){
		delete v;
		delete n;
		return 0;
	}
	if(stricmp(*n,"recordNo")==0){
		if(v!=0){
			recordNo=atoi(*v);
			if(data->exists(recordNo)==0){
				recordNo=0;
			}
		}else
			recordNo=0;
		delete n;
		delete v;
		return 0;
		
	}else
		if(stricmp(*n,"fieldList")==0){
			delete fieldList;
			fieldList=v;
			delete n;
			return 0;
		}else
		if(stricmp(*n,"record")==0){
			File *f=v->getFile();
			if(f!=0){
				htmlObject *o= new htmlObject(new Buffer("record",7));
				fileStream *fs=new fileStream(f);
				f->seekTo(0);
				inputStream *in=new inputStream(fs);
				o->readForm(in);
				recordNo=data->importData(o);
				delete o;
				delete fs;
				delete in;
			}
			delete n;
			delete v;
			return 0;
		}
	miner *m=new miner();
	Buffer *fn=0;
	if(m->mine(*n,"`*`(*)"))
		fn=m->getValueFinal(0);
	else{
		if(v->next==0 && v->getFile()==0){
			int r=data->getKeyRecord(*n,*v);
			if(r!=0){
				recordNo=r;
			}
		}
	}
	delete m;
	if(fn){
		trim(fn);
		if((recordNo > 0) && (check(*fn)==0)){
			htmlBuffer *z=data->getFieldValue(recordNo,*fn);
			if(z){
				htmlObject::putValue(fn,z);
				fn=0;
			}
		}
		delete fn;
	}else{
		if((v->getFile()==0) && (stricmp(*v,NULLVALUE)==0) && stricmp(*n,"delim")){;
			htmlObject::putValue(n,(htmlBuffer*)0);
		}
	}
	return(htmlObject::putValue(n,v));
}


int htmlTable::addValue(Buffer *name,htmlBuffer* val)
{
	if(data && name && val && recordNo){
		if(stricmp("recordNo",*name)==0){
			int n=atoi(*val);
			if(n!=0){
				if(selection)
					recordNo=selection->getNext(recordNo,n*order);
				else
					recordNo=data->getNext(recordNo,n*order);
			}
		}else{
			miner *m=new miner();
			Buffer *fn=name;
			if(m->mine(*name,"`*`(*)"))
				fn=m->getValueFinal(0);
			delete m;
			if(recordNo > 0 && fn && check(*fn)==0){
				htmlBuffer *z=data->getFieldValue(recordNo,*fn);
				if(z){
					htmlObject::putValue(fn,z);
					if(name==fn)
						name=new Buffer(*fn,fn->getSize());
					fn=0;
				}
			}
			if(fn!=name)
				delete fn;
			return(htmlObject::addValue(name,val));
        }
	}
	deleteHtmlBuffer(val);
	delete name;
	return 0;
}

int htmlTable::subValue(Buffer *name,htmlBuffer* val)
{
	if(data && name && val && recordNo){
		if(stricmp("recordNo",*name)==0){
			int n=atoi(*val)*-1;
			if(n!=0){
				if(selection)
					recordNo=selection->getNext(recordNo,n*order);
				else
					recordNo=data->getNext(recordNo,n*order);
			}
		}else{
			miner *m=new miner();
			Buffer *fn=name;
			if(m->mine(*name,"`*`(*)"))
				fn=m->getValueFinal(0);
			delete m;
			if(recordNo > 0 && fn && check(*fn)==0){
				htmlBuffer *z=data->getFieldValue(recordNo,*fn);
				if(z){
					htmlObject::putValue(fn,z);
					if(name==fn)
						name=new Buffer(*fn,fn->getSize());
					fn=0;
				}
			}
			if(fn!=name)
				delete fn;
			return(htmlObject::subValue(name,val));
        }
	}
	delete name;
	deleteHtmlBuffer(val);
	return 0;
}


int htmlTable::divValue(Buffer *name,htmlBuffer* val)
{
	if(data && name && val && recordNo){
		if(stricmp("recordNo",*name)){
			miner *m=new miner();
			Buffer *fn=name;
			if(m->mine(*name,"`*`(*)"))
				fn=m->getValueFinal(0);
			delete m;
			if(recordNo > 0 && fn && check(*fn)==0){
				htmlBuffer *z=data->getFieldValue(recordNo,*fn);
				if(z)
					htmlObject::putValue(fn,z);
				if(z){
					htmlObject::putValue(fn,z);
					if(name==fn)
						name=new Buffer(*fn,fn->getSize());
					fn=0;
				}
			}
			return(htmlObject::divValue(name,val));
        }
	}
	delete name;
	deleteHtmlBuffer(val);
	return 0;
}

int htmlTable::modValue(Buffer *name,htmlBuffer* val)
{
	if(data && name && val && recordNo){
		if(stricmp("recordNo",*name)){
			miner *m=new miner();
			Buffer *fn=name;
			if(m->mine(*name,"`*`(*)"))
				fn=m->getValueFinal(0);
			delete m;
			if(recordNo > 0 && fn && check(*fn)==0){
				htmlBuffer *z=data->getFieldValue(recordNo,*fn);
				if(z){
					htmlObject::putValue(fn,z);
					if(name==fn)
						name=new Buffer(*fn,fn->getSize());
					fn=0;
				}
			}
			if(fn!=name)
				delete fn;
			return(htmlObject::modValue(name,val));
        }
	}
	delete name;
	deleteHtmlBuffer(val);
	return 0;
}



int htmlTable::mulValue(Buffer *name,htmlBuffer* val)
{
	if(data && name && val &&  recordNo){
		if(stricmp("recordNo",*name)){
			miner *m=new miner();
			Buffer *fn=name;
			if(m->mine(*name,"`*`(*)"))
				fn=m->getValueFinal(0);
			delete m;
			if(recordNo > 0 && fn && check(*fn)==0){
				htmlBuffer *z=data->getFieldValue(recordNo,*fn);
				if(z){
					htmlObject::putValue(fn,z);
					if(name==fn)
						name=new Buffer(*fn,fn->getSize());
					fn=0;
				}
			}
			if(fn!=name)
				delete fn;
			return(htmlObject::mulValue(name,val));
        }
	}
	delete name;
	deleteHtmlBuffer(val);
	return 0;
}



htmlBuffer* htmlTable::getValue(htmlBuffer* name)
{
	    char* x=*name;
		if(stricmp(x,"selected")==0){
			char b[12];
			snprintf(b,12,"%d",selected);
			return(new htmlBuffer(b));
		}else{
			if(stricmp(x,"recordNo")==0){
				char b[12];
				snprintf(b,12,"%d",recordNo);
				return(new htmlBuffer(b));
			}else
				if(stricmp(x,"dblist")==0){
					return dbms->list();
				}else
				if(stricmp(x,"tablelist")==0){
					return dbms->list(cid);
				}
		}
        if(data==0)
		 return 0;
		if(stricmp(x,"nextRecord")==0){
			if(recordNo>0){
				if(selection!=0){
					recordNo=selection->getNext(recordNo,order);
				}else{
					recordNo=data->getNext(recordNo,order);
				}
			}
			return(0);
		}else
		if(stricmp(x,"selectAll")==0){
			deleteSelection();
			if(data->exists()){
				recordNo=(*data)[1];
				selected=data->getTotal();
			}
			return 0;
		}else
		if(stricmp(x,"insert")==0){
			recordNo=data->insertRow(this);
			cleanup();
			return 0;
		}else
		if(stricmp(x,"tableInfo")==0){
			File *f=data->getTableInfo();
			return(new htmlBuffer(f));
		}else
		if(stricmp(x,"tablename")==0){
			char* s = data->getName();
			return new htmlBuffer(new Buffer(s,strlen(s)+1));
		}else
		if(stricmp(x,"restoreSelection")==0){
			deleteSelection();
			if(savedSelected!=0){
				if(savedSelection!=0){
					selection=savedSelection;
					selected=selection->getTotal();
					order=selection->getOrder();
				}else{
					selected=savedSelected;
				}
				recordNo=savedRecordNo;
			}
			return(0);
		}
		if(recordNo<=0)
			return 0;
		if(stricmp(x,sPACKED)==0){
			if(data->exists()){
				genericObject* cc=data->exportData(recordNo,fieldList,0);
				htmlBuffer* pc=cc->getValue(sPACKED);
				delete cc;
				return pc;
			}
		}else
		if(stricmp(x,"asc")==0){
			order=1;
			if(selection!=0){
				recordNo=selection->getNext(0,1);
			}else{
				recordNo=(*data)[1];
			}
			return 0;
		}else
		if(stricmp(x,"desc")==0){
			order=-1;
			if(selection!=0){
				recordNo=selection->getNext(0,-1);
			}else{
				recordNo=data->getTotal();
				if(recordNo<0)
					recordNo=0;
				else
					recordNo=(*data)[recordNo];
			}
			return 0;
		}else
		if(((stricmp(x,"modify")==0) || (stricmp(x,"update")==0))){
			data->updateRecord(this,recordNo);
			cleanup();
			return 0;
		}else
		if(stricmp(x,"deleteRecord")==0){
			if(recordNo>0){
				int tr=0;
				if(selection)
					tr=selection->getNext(recordNo,order);
				else
					tr=data->getNext(recordNo,order);
					data->deleteRecord(recordNo);
					recordNo=tr;
			}
			return 0;
		}else
		if((stricmp(x,"lastrecord")==0) || (stricmp(x,"prevrecord")==0)){
			if(selection!=0){
				recordNo=selection->getNext(recordNo,-1*order);
			}else{
				recordNo=data->getNext(recordNo,-1*order);
			}
			return 0;
		}else
		if(stricmp(x,"unlockRecord")==0){
			data->unlockTable(recordNo,uid);
			return(0);
		}else
		if(stricmp(x,"lockRecord")==0){
			data->lockTable(recordNo,uid,thread,1);
			return(0);
		}else
		if(stricmp(x,"lockSelection")==0){
			if(selection!=0){
				recordNo=selection->getNext(recordNo,order);
			}else{
				recordNo=data->getNext(recordNo,order);
			}
			return(0);
		}else
		if(stricmp(x,"saveSelection")==0){
			if(selection!=0){
				if(savedSelection!=selection){
					delete savedSelection;
				}
			}
			savedSelection=selection;
			savedSelected=selected;
			savedRecordNo=recordNo;
			return(0);
		}else
		if(stricmp(x,"firstRecord")==0){
			if(selection){
				selected=selection->getTotal();
				recordNo=selection->getNext(0,order=selection->getOrder());
			}else{
				if(data){
					if(data->exists()){
						recordNo=(*data)[1];
						selected=data->getTotal();
					}
				}
			}
			return 0;
		}else{
			miner *m= new miner();
			if(m->mine(x,"recordNo~%`#~#`~%")){
				char b[12];
				int r=1;
				int n=atoi(m->getValue(0));
				if(selection!=0)
					r=selection->getNext(recordNo,n*order,1);
				else
					r=data->getNext(recordNo,n*order);
				snprintf(b,12,"%d",r);
				delete m;
				return(new htmlBuffer(b));
			}else{
				if(m->mine(x,"recordNo~%-~%`#~#`~%")){
					char b[12];
					int n=atoi(m->getValue(0))*-1;
					int r=1;
					if(selection!=0)
						r=selection->getNext(recordNo,n*order,1);
					else
						r=data->getNext(recordNo,n*order);
					snprintf(b,12,"%d",r);
					delete m;
					return(new htmlBuffer(b));
				}
			}
			delete m;
			int n=strlen(x)-1;
			if((n>0) && (x[n]=='_')){
				for(;n>0;--n){
					if(x[n]=='.')
						break;
				}
				if(x[n]=='.'){
					x[n]=0;
					if(stricmp(x+n+1,"max_")==0){
						return getMax(x,-1);
					}else
						if(stricmp(x+n+1,"min_")==0){
							return getMax(x,0);
						}else{
							int tr;
							if(selection!=0){
								tr=selection->getNext(0,1);
							}else{
								tr=(*data)[1];
							}
							int avg=1;
							if(stricmp(x+n+1,"sum_")==0 || (avg=stricmp(x+n+1,"avg_"))==0){
								int cnt=0;
								double f=0;
								while(1){
									htmlBuffer *v=data->getValue(cid,tr,x);
									if(v!=0){
										cnt++;
										f+=atof(*v);
										delete v;
									}
									int tn=0;
									if(selection)
										tn=selection->getNext(tr,1);
									else
										tn=data->getNext(tr,1);
									if(tn==tr || tn==0)
										break;
									tr=tn;
								}
								if((avg==0) && (cnt>0)){
									f/=cnt;
								}
								char tmp[32];
								snprintf(tmp,32,"%.4f",f);
								return(new htmlBuffer(tmp));
							}
						}
						x[n]='.';
				}
			}
			if(recordNo){
					return data->getValue(cid,recordNo,x);

			}
		}
  return 0;
} 

htmlBuffer* htmlTable::getMax(char* field,int order)
{
	if(data){
		Buffer * cursel=0;
		if(selected==0)
			cursel=new Buffer(0);
		else{
			if(selection)
				cursel = selection->getBuffer();
		}
		Buffer *z=new Buffer(strlen(field)+16);
		snprintf(*z,z->getSize()-1,"order by %s",field);
		Selection *ts=data->getSelection(cid,z,cursel);
		if(ts!=0){
			int tr=0;
			if(ts!=ALLSELECTED){
				tr=ts->getNext(0,order);
				delete ts;
			}
			if(tr!=0)
				return data->getValue(cid,tr,field);
		}
    }
	return 0;
}


void htmlTable::select(Buffer* query,int add)
{
	if(data){
		Buffer * cursel=0;
		if(selected==0)
			cursel=new Buffer(0);
		else{
			if(selection)
				cursel = selection->getBuffer();
		}
		deleteSelection();
		if((selection=data->getSelection(cid,query,cursel,add))!=0){
			if(selection==ALLSELECTED){
				deleteSelection();
				selected=data->getTotal();
				recordNo=(*data)[1];
			}else{
				selected=selection->getTotal();
				recordNo=selection->getNext(0,order=selection->getOrder());
			}
		}
    }else
		delete query;
}





void fixOriginal(char* s,int l)
{
	int flip=0;
	for(int i=0;i<l;++i){
		if(s[i]=='"'){
			flip^=1;
			s[i]='~';
		}else{
			if(flip)
				s[i]^=0xff;
		}
	}
}


void htmlTable::executeQuery(Buffer *z,genericObject* f,int add)
{
	if(z!=0){
		if(f!=0){
			miner *n = new miner();
			Buffer *queryString = new Buffer(2048);
			char *q=*queryString;
			char *qe=q+queryString->getSize()-48;
			int l;
			while(n->mine(*z,"`*`{`*`}`*`")){
				delete z;
				z=n->getValueFinal(1);
				trim(z);
				htmlBuffer *sql=new htmlBuffer(z);
				htmlBuffer* v=f->getValue(sql);
				delete sql;
				z=n->getValueFinal(2);
				char *u=n->getValue(0);
				l=strlen(u);
				if(q+l<qe){
					int fix=(u[l-1]=='"');
					memcpy(q,u,l);
					q+=l;
					if(v){
						l=v->getSize()-1;
						if(l>0){
							char *s=*v;
							if(q+l<qe){
								if(fix){
									q--;
									*q++='^';
									for(int i=0;i<l;++i)
										q[i]=s[i]^0xff;
								}
								else{
									memcpy(q,s,l);
									fixOriginal(q,l);
								}
							}
						}
						deleteHtmlBuffer(v);
						q+=l;
					}
				}
				if(z==0)
					break;
			}
			if(z!=0){
				l=z->getSize()-1;
				if(q+l<qe){
					char* u=*z;
					memcpy(q,u,l);
					q+=l;
				}
				delete z;
			}
			*q++=0;
			delete n;
			queryString->setSize(q-(char*)*queryString);
			select(queryString,add);
		}else
			select(z,add);
	}
}



class dhtmlCode{
   protected:
   enum INSTRUCTION{
             invalidCode,
             outputParam,
             moveParamToRegisterA,
             includeFileRegister,
             includeFile,
             moveParamToRegisterB,
             moveRegisterAtoB,
             outputRegister,
             closeOutput,
			 setModeReg,
             quit,
			 quitLoops,
             setMode,
             setEOL,
             substituteString,
			 moveParamToRegisterC,
			 eventHandler,
			 suspend,
			 moveRegisterAtoC,
			 putRegisterA,
			 putToken,
			 putQuot,
			 pushAcc,
			 popAcc,
			 moveAccToRegisterA,
			 popAccToRegisterA,
			 switchCase,
			 flushData,
             writeToFile,
             appendToFile,
			 OBJECTCODES,
			 dispatch,
			 redirect,
             domainCheck,
			 adminCheck,
             chkIfObjZero,
			 checkIfEventHandler,
             getValueRegister,
             putValueRegisterB,
             loopStart,
             repeatLoop,
			 rmLoop,
             createVar,
             createTime,
             addValueRegisterB,
             subValueRegisterB,
             divValueRegisterB,
             mulValueRegisterB,
             modValueRegisterB,
			 exec,
			 execp,
             createTable,
             createFile,
             packObjectA,
             createUser,
             createForm,
             execPrgm,
             createFolder,
             createFTP,
             unpackVar,
             createHost,
             createObject,
             createObjectFromFile,
             createMail,
			 createSearch,
             unpackForm,
             sqlQuery,
			 alsoQuery,
			 writeToFileObj,
             unpackMail,
             deleteObject,
			 createParser,
			 createQueue,
			 readMail,
			 appendToFileObj,
			 Lock,
			 Release,
			 registerFile,
			 rebuild,
			 JUMPCODES,
			 jmpLabel,
             jmp,
			 ejmp,
			 sjmp,
			 jmpIfNotTrue,
             jmpIfValueZero,
			 SleepSec,
			 returnBack,
			 putOp,
			 NOP
           };


struct  htmlCode {
	  BYTE dummy;
      BYTE Instruction;
	  USHORT object;
      Buffer* param;
      };
   };

#define MUSTGET 1
#define USEPTR  2
#define INDIRECT 4


typedef struct{
	char** symbols;
	genericObject** objects;
	int symtotal;
}symTab;


int  getSymbol(char *name,char **symbols,int *symtotal,int put=0)
{
	int m,d;
	int b=0;
	int e=*symtotal-1;
	while(e>=b){
		m = (b+e)/2;
		if((d=stricmp(symbols[m],name))<0)
			b=m+1;
		else
			if(d>0)
				e=m-1;
			else{  
				return m;
			}
	}
	if(put){
		for(int p=*symtotal;p>b;p--)
			symbols[p]=symbols[p-1];
		(*symtotal)++;
		symbols[b]=name;
		return b;
	}
	return 0;
}

class dhtml : public URLhandler,public dhtmlCode{
   Buffer *codeStorage;
   htmlCode* codeBuff;
   int ip;
   ULONG ftime;
   int lock;
   mutex *mlock;
   Buffer *symbuff;
   char **symbols;
   int symtotal;
   int eventAt;
   int cookieAt;
   int outputLine(char*,RealFile *outFile,char* linefeed,char* para,HFILE writer);
//   int outputFromFile;
//   int outputFile;
   public:
   dhtml(char* url,Buffer *codes,Buffer* syms) 
	   :URLhandler(url),codeStorage(codes),ftime(getTime()),lock(0),mlock(0),symbuff(syms)
   {
	   codeBuff=(htmlCode*)((char*)*codeStorage);
	   adjust();
	   ip=codeStorage->getSize()/sizeof(htmlCode);
   }
   ~dhtml(){for (int i=0;i<ip;++i) if(codeBuff[i].Instruction<JUMPCODES) delete codeBuff[i].param; delete codeStorage; delete symbuff;}
   virtual void refresh(File *f=0);
   void adjust()
   {
       symbols=(char**)((char*)*symbuff);
	   symtotal=symbuff->getSize()/sizeof(char*);
	   eventAt=getSymbol("_event",symbols,&symtotal);
       cookieAt=getSymbol("cookie",symbols,&symtotal);
   }
   void output(genericObject *fobj,Runnable*,File * of);
};


#define YEAR 0
#define MONTH 1
#define DATE 2
#define HOUR 3
#define MINUTE 4
#define DAY 5
#define MAXSCH 32
#define ALL -1
#define NEVER -2


typedef struct SCH{
   int count;
   Buffer *deleteThis;
   int sch[6][MAXSCH+1];
   class dhtml *dhtml;
   SCH *next;
   int runcount;
   class runner* worker;
   }SCHEDULE;

Buffer* recompile(File* f,SCHEDULE **newsch,Buffer **symbuff);

static SCHEDULE  *schedules=0;

void addNewSch(SCHEDULE *newsch)
{
	SCHEDULE *sch,*prev=0;
	char *s=newsch->dhtml->getName();
	for(sch=schedules;sch!=0;sch=sch->next){
		if(stricmp(s,sch->dhtml->getName())==0){
			sch->count=newsch->count;
			memcpy(sch->sch,newsch->sch,sizeof(sch->sch));
			sch->dhtml=newsch->dhtml;
			delete newsch->deleteThis;
			break;
		}
		prev=sch;
	}
	if(sch==0){
		newsch->worker=0;
		newsch->next=0;
		newsch->runcount=0;
		if(prev==0)
			schedules=newsch;
		else
			prev->next=newsch;
	}
}

void remSch(char* s)
{
	SCHEDULE *sch;
	for(sch=schedules;sch!=0;sch=sch->next){
		if(stricmp(s,sch->dhtml->getName())==0){
			sch->count=0;
			break;
		}
	}
}

void dhtml::refresh(File *vf)
{
	if(lock==0){
		int dif=0;
		ULONG ft;
		File *f=vf;
		if(f==0)
			f=new File(templatePath,getName());
		if(f->exists()){ 
			ft=f->lastWriteTime();
			dif=ft-ftime;
			if((dif>0) || (vf!=0)){
				ftime=ft;
				SCHEDULE *sch=0;
				delete symbuff;
				Buffer* tmp=recompile(f,&sch,&symbuff);
				EnterCritSec();
				Buffer* oldcode=codeStorage;
				codeStorage=tmp;
				codeBuff=(htmlCode*)((char*)*codeStorage);
				int oldip=ip;
				ip=codeStorage->getSize()/sizeof(htmlCode);
				htmlCode* codeBuff=(htmlCode*)((char*)*oldcode);
				adjust();
//				symbols=(char**)((char*)*symbuff);
//				symtotal=symbuff->getSize()/sizeof(char*);
				for(int i=0;i<oldip;++i){
					if(codeBuff[i].Instruction < JUMPCODES)
						delete codeBuff[i].param;
				}
				delete oldcode;
				if(sch){
					setScheduler(1);
					sch->dhtml=this;
					addNewSch(sch);
				}
				else
					if(isScheduler()){       
						remSch(getName());
					}
					ExitCritSec();
			}
		}
		if(vf==0)
			delete f;
	}
}







int matchSch(int a, int *b)
{
   for(int i=0;i<MAXSCH;++i){
      if(b[i]<0)
         break;
      if(b[i]==a)
         return 1;
      }
return 0;
}


class scheduler : public virtual ThreadSafe, public Runnable{
   void run();
   public:
   scheduler() {start();}
   };


class runner : public virtual ThreadSafe, public Runnable{
   htmlObject* request;
   SCHEDULE *sch;
   void run();
   public:
	   runner(SCHEDULE *s) : sch(s) {request=getGlobals();}
	   ~runner();
   };



runner::~runner()
{
	for(genericObject *tmp=request;tmp!=0;){
		genericObject *dl=tmp->next;
		delete tmp;
		tmp=dl;
	}
}

#define SYMINFO "_\r\n!"
char *stayAlive="stayAlive";

void runner::run()
{
	request->setReadWrite();
	request->putValue(xauth,NULLVALUE);     
   	request->putValue(xauth,getXauth());
	request->setReadOnly();
	sch->dhtml->open(this,request,Console);
	genericObject* po=0;
	genericObject* pl=0;
	for(genericObject *tmp=request->next;tmp!=0;){
		genericObject *dl=tmp->next;
		if(tmp->ifPersistent()==0){
			if(tmp->getType()==TYPFORM){
				if(tmp->submit()==0){
					delete tmp;
				}
			}else
				delete tmp;
		}
		else{
			if(po==0)
				po=tmp;
			else
				pl->next=tmp;
			pl=tmp;
		}
		tmp=dl;
	}
	request->next=po;
	if(pl)
		pl->next=0;
	if((sch->count>0) && (request->showValue(stayAlive)==0))
		sch->count--;
	request->putValue("stayAlive","null");
	sch->runcount++;
}


class eventHandler : public virtual ThreadSafe, public Runnable{
	char *qtype;
	char *qdomain;
	char *urlname;
	void run();
	int hId;
public:
	eventHandler(char* code, char* type,char* domain,int id) : qtype(type),qdomain(domain),urlname(code),hId(id){start();}
};




extern char tmpDirectory[];
extern char etcDirectory[];

Runnable* getEventHandler(char *u,char* type,char* domain,int id)
{
 return new eventHandler(u,type,domain,id);
}


void eventHandler::run()
{
	SafeStart();
	URLhandler *url=getURLhandler(urlname);
	if(url==0)
		return;
	htmlObject* request=getGlobals();
	request->putValue("A\r\nA",qtype);
	if(qdomain)
		request->putValue("B\r\nB",qdomain);
	request->setInstance(hId);
	int chk=0;
	ULONG st=0;
	while(1){
		SleepMilSec(1);
		int cn=checkQueue(qtype,qdomain);
workQ:
		if(cn==0 || timeToSendQueueItem(cn)==0){
			goto skipThis;
		}else{
			request->setReadWrite();
			request->putValue(xauth,NULLVALUE);     
			request->putValue(xauth,getXauth());
			request->setReadOnly();
			eventSetId(hId,cn);
			url->open(this,request,Console);
			st=0;
			genericObject* po=0;
			genericObject* pl=0;
			for(genericObject *tmp=request->next;tmp!=0;){
				genericObject *dl=tmp->next;
				if(tmp->ifPersistent()==0){
					if(tmp->getType()!=TYPFORM || tmp->submit()==0)
						delete tmp;
				}else{
					if(po==0)
						po=tmp;
					else
						pl->next=tmp;
					pl=tmp;
				}
				tmp=dl;
			}
			request->next=po;
			if(pl)
				pl->next=0;
			cn=checkQueue(qtype,qdomain);
			if(cn!=0 && cn!=chk){
				chk=cn;
				goto workQ;
			}
		}
skipThis:
		if(cn==0){
			if(st==0)
				st=getTime();
			Suspend();
		}else{
			SleepMilSec(1);
			if((cn==chk) || (timeToSendQueueItem(cn)==0)){
				SleepMilSec(10000);
			}
		}
		chk=checkQueue(qtype,qdomain);
		if(Quit()){
			SleepMilSec(2000);
			break;
		}else{
			if(st && ((chk==0) && ((getTime()-st) >= 60))){
				break;
			}
		}
	}
	while(request){
		genericObject *dl=request->next;
		delete request;
		request=(htmlObject*)dl;
	}
}


int cleanSearchDataBase();
void timeoutUsers();
int flushFiles();
int closeFiles();
void freeCache();
int shutcaravan=0;

Time *timeschedule;
ULONG tvcount;

void initTimeSchedule()
{
	timeschedule=new Time();
    tvcount=*timeschedule;
}

void scheduler::run()
{
	SleepMilSec(1000);
	int count=0;
	int cleanupHour=3;
	char *dfr=(*serverConfig)["cleanuphour"];
	if (dfr && *dfr)
		cleanupHour=atoi(dfr);
	while(1){
#ifdef TARGETLINUX
		void postEvents();
		postEvents();
#endif
		freeCache();
		closeOpenSock();
		if(shutcaravan){
			flushFiles();
			flushSeeker();
			shutDown();
			SleepMilSec(2000);
			exit(0);
		}else{
			if(count%20==1){
				flushFiles();
				flushSeeker();
			}
		}
		tvcount++;
		if(++count==60){
			count=0;
			timeschedule->SetTime(tvcount);
			timeoutUsers();
			if(timeschedule->getHours()==cleanupHour){
				char *dday=(*serverConfig)["cleanupday"];
				int day=1;
				if(dday && *dday){
					Buffer *b=timeschedule->getDayString();
					if(strnicmp(dday,*b,3)!=0)
						day=0;
					delete b;
				}
				int sw=0;
				for(SCHEDULE *s=schedules;s!=0;s=s->next){
					if ((s->worker!=0) &&	(s->worker->alive()!=0))
						sw++;
				}
				if ((day==1) && (sw==0) && (cleanSearchDataBase()!=0)){
					tvcount=getTime();
				}
			}
			for(SCHEDULE *s=schedules,*prev=0;s!=0;){
				if(s->count!=0 && (s->worker==0 || !s->worker->alive()))
					if(s->sch[YEAR][0]==ALL || matchSch(timeschedule->getYear(),s->sch[YEAR]))
						if(s->sch[MONTH][0]==ALL || matchSch(timeschedule->getMonth(),s->sch[MONTH]))
							if(s->sch[DATE][0]==ALL || matchSch(timeschedule->getDate(),s->sch[DATE]))
								if(s->sch[DAY][0]==ALL || matchSch(timeschedule->getDay(),s->sch[DAY]))
									if(s->sch[HOUR][0]==ALL || matchSch(timeschedule->getHours(),s->sch[HOUR]))
										if(s->sch[MINUTE][0]==ALL || matchSch(timeschedule->getMins(),s->sch[MINUTE])){
											if(s->worker==0)
												s->worker=new runner(s);
											s->worker->start();
										}
										if(s->count==0){
											s->dhtml->setScheduler(0);
											delete s->worker;
											if(prev==0){
												schedules=s->next;
												delete s->deleteThis;
												if(schedules==0)
													break;
												s=schedules;
											}else{
												prev->next=s->next;
												delete s->deleteThis;
												s=prev->next;
											}
										}else{
											prev=s;
											s=s->next;
										}
			}
		}
		SleepMilSec(1000);
	}
}


#define LABLS 32
#define LABPOINTS 32
#define MAXCODE 8192*2



class dhtmlCompiler : public ThreadSafe , public dhtmlCode{
	enum{DUM,OP,PUSH,POP,QUOT,TOKEN,VAR,RAW};
	typedef struct{
		int jmppoint;
		char label[64];
		int ip[LABPOINTS];
	}labels;      
	typedef struct {
        int id;
        Buffer *string;
	}Item;
	Item items[2048];
	typedef struct{
		int id;
		int ip;
	}BreakInfo;
    char* symbols[1024];
	BreakInfo breaks[512];
	int bt;
	int bp;
	typedef struct{
		int swstart;
		int swend;
		int defaultIp;
		int elements;
		Buffer *elementBuffer;
		Buffer** cases;
	}SWInfo;
	SWInfo swpt[32];
	int sw;
	int id;
	char *compiling;
	void insertPush(int fixid);
	char* getToken(char** next);
	Buffer* isIf(Buffer* x,miner *n);
	int parseExp(char* string);
	int evaluate(int cid,int *err);
	labels labl[LABLS];
	int ip;
	htmlCode codeBuff[MAXCODE];
	htmlCode *jump[64];
	int cjump;
	char errorString[256];
	int ifs;
	int ifcount;
	SCHEDULE *sch;
	int compile(miner*,Buffer*);
    void putNumValue(int numAccId,double numAcc,int prec,int itype);
	int evaluateVar(Buffer* x,miner*);
	int evaluateExp(Buffer** x,miner *n);
	int checkAssignment(Buffer* x, miner *n);
	int checkAddition(Buffer* x, miner *n);
	int checkDiv(Buffer* x, miner *n);
	int checkMul(Buffer* x, miner *n);
	int checkSubstitute(Buffer* x, miner *n);
	int checkMod(Buffer* x, miner *n);
	int checkSubstraction(Buffer* x, miner *n);
	int checkVar(Buffer* x, miner *n);
	int checkForm(Buffer* x, miner *n);
	int checkMail(Buffer* x, miner *n);
	int checkTime(Buffer* x, miner *n);
	int checkTable(Buffer* x, miner *n);
	int checkInclude(Buffer* x, miner *n);
	int checkLoopStart(Buffer* x, miner* n);
	int checkLoopEnd(Buffer* x, miner* n);
	int checkOutput(Buffer* x, miner* n);
	int checkQueue(Buffer* x, miner* n);
	int checkEventHandler(Buffer* x, miner* n);
	int checkCloseOutput(Buffer* x, miner* n);
	int checkQuery(Buffer* x, miner* n);
	int checkElse(Buffer* x, miner*n);
	int makeElse();
	int makeElseIf();
	int checkEndIf(Buffer* x, miner*n);
	int checkIfTrue(Buffer* x, miner*n);
	int checkOver(Buffer* x, miner *n);
	int checkQuitLoops(Buffer* x, miner *n);
	int checkSuspend(Buffer* x, miner *n);
	int checkBreak(Buffer* x, miner *n);
	int checkDelete(Buffer* x, miner *n);
	int checkRegister(Buffer* x, miner *n);
	int checkFlush(Buffer* x, miner *n);
	int checkRebuild(Buffer* x, miner *n);
	int checkMode(Buffer*x, miner *n);
	int checkIfDomain(Buffer*x, miner *n);
	int checkFile(Buffer* x,miner* n);
	int checkUser(Buffer* x,miner* n);
	int checkExec(Buffer *x,miner *n);
	int checkCmd(Buffer *x,miner *n);
	int checkString(Buffer* x,miner* n);
	int checkSchedule(Buffer* x,miner *n);
	int checkFolder(Buffer* x, miner *n);
	int checkFTP(Buffer* x, miner *n);
	int checkHost(Buffer* x, miner *n);
	int checkObject(Buffer* x, miner *n);
	int checkLabel(Buffer* x, miner *n);
	int checkSleep(Buffer* x, miner *n);
	int checkLock(Buffer* x, miner *n);
	int checkRelease(Buffer* x, miner *n);
	int checkGoto(Buffer* x, miner *n);
	int checkDispatch(Buffer* x, miner *n);
	int checkSwitch(Buffer* x, miner *n);
	int checkSwitchEnd(Buffer* x, miner *n,int fin=0);
	int checkDefault(Buffer* x, miner *n);
	int checkCase(Buffer* x, miner *n);
	void readFile(File *f,char* fname);
	void adjustBreaks();
	void putBreak();
   public:
	   Buffer* compile(File*f,char* fname,Buffer **sym);
	   void compile(File* f);
	   SCHEDULE* getSch() { return sch;}
};



void dhtmlCompiler::insertPush(int fixid)
{
	memmove(items+fixid+1,items+fixid,(id-fixid)*sizeof(Item));
	items[fixid].id=PUSH;
	items[fixid].string=0;
	id++;
}

enum        {MATCH,DOT,ADD,SUB,MUL,DIV,MOD,EQU,GTE,LTE,NTE,GT,LT,OR,AND,CMT};
char Prec[]=		{8,   10,  10,	 10, 13, 13, 11, 8,  8,  8,	 8,  8,	 8,	 5,	 5,  5,  5,   5,	0};
int opCode[]=		{CMT, NTE, MATCH,DOT,ADD,SUB,MUL,DIV,MOD,EQU,EQU,GTE,LTE,NTE,GT, LT, OR,  AND};
char *operators[]=	{"//","!=","=~",".","+","-","*","/","%","==","=",">=","<=","<>",">","<","||","&&",0};

int isOperator(char* c)
{
		for(int i=0;operators[i]!=0;++i){
			int l=strlen(operators[i]);
			if(strnicmp(operators[i],c,l)==0){
				return l;
			}
		}
        return 0;
}

int whichOperator(char* c)
{
        for(int i=0;operators[i]!=0;++i){
			int l=strlen(operators[i]);
			if(strnicmp(operators[i],c,l)==0){
				return opCode[i];
			}
		}
        return 0;
}




int getExp(char** next)
{
	int count=1;
	char *s=*next;
	s++;
	while(*s){
		if(*s==')'){
			count--;
			if(count==0){
				*next = s;
				return 1;
			}
		}else{
			if(*s=='"'){
				s++;
				while(*s!='"'){
					if(*s=='\\')
						s++;
					if(*s==0){
						*next="Missing \"";
						return 0;
					}
					s++;
				}
			}else{
				if(*s=='(')
					count++;
			}
		}
		s++;
	}
	if(count>0){
		*next="Missing ')'";
		return 0;
	}
	*next=s;
	return 1;
}


char* dhtmlCompiler::getToken(char** next)
{
        char *s=*next;
        char *string;
        while(*s==' ' || *s == '\t') s++;
        if(*s==0)
                return *next=s;
        if(*s=='"'){
                string=s++;
                while(*s!='"'){
                        if(*s=='\\')
                                s++;
                        if(*s==0){
                                *next="Missing \"";
                                return 0;
                        }
                        s++;
                }
                *next=s;
                return string;
        }
        string = s;
        if(*s=='('){
                if(getExp(&s)){
                        *s++=0;
                        while(*s && !isOperator(s)){
                                if(*s>' '){
                                        *next="Unexpected Char -";
                                        return 0;
                                }
                                s++;   
                        }
                        *next=s;
                        return string;
                }else{
                        *next=s;
                        return 0;
                }
        }
        for(int g=0;*s!=0;s++){
			if(isOperator(s)){
				if((s==string) || (g!=0))
					break;
				char c=*s;
				*s=0;
				int prec;
				int wp=getbType(string,&prec);
				*s=c;
                if(wp<2){
					if(prec==0 && c == '.')
						continue;
					else
					   break;
				}              
				wp=whichOperator(s);
				if(wp <= ADD || wp >=EQU)
					break;
			}else
			if(*s=='('){
				if(getExp(&s)==0){
					*next=s;
					return 0;
				}
				while(*(s+1)==' ' || *(s+1)=='\t')
					s++;
				g=1;
			}else
				g=0;
        }
        while(*string && (*string<=' '))
                string++;
        *next=s;
        return string;
}


typedef struct{
	int pv;
	int id;
}PRE;


int dhtmlCompiler::parseExp(char* string)
{
        char end=*string;
		int startId=id;
		PRE pr[32];
		int sp=0;
		pr[0].id=id;
		pr[0].pv=0;
		int opid=id;
		char opb[8];
		opb[0]=0;
        while(end){
			char *token=getToken(&string);
			if(token==0){
				printf("Error in %s : %s\n",compiling,string);
				return 0;
			}
			int l=isOperator(string);
			char op[8];
			*op=0;
			if(l>0){
				if(whichOperator(string)==CMT){
					l=0;
					*string=0;
				}else{
					strncpy(op,string,l);
					op[l]=0;
				}
			}else {
				l=1;
			}
			end=*string;
			*string=0;
			switch(*token){
			case  0: 
				break;
			case '(':		
				{
					if(opb[0]=='-'){
						items[id].string=new Buffer("-1",3);
						items[id++].id=TOKEN;
						items[id].id=OP;
						items[id++].string=new Buffer("*",2);
						if(pr[sp].pv<13){
							sp++;
							pr[sp].pv=13;
							pr[sp].id=opid;
						}
						opid=id;
					}
					opb[0]=0;
					token++;
					int pid=id;
					items[id++].id=PUSH;
					int prc=parseExp(token);
					token[strlen(token)]=')';
					if(prc>0){
						if(id-pid<3){
							id--;
							if(id!=pid){
								memcpy(&items[pid],&items[id],sizeof(Item));
								memset(&items[id],0,sizeof(Item)*(id-pid));
								id=pid+1;
							}
						}
						else{
							items[id++].id=POP;
						}
					}else
						return 0;
				}
				break;
			case '"':
				{
				opb[0]=0;
				items[id].id=QUOT;
				int l=strlen(token);
				Buffer *b=new Buffer(token,l+2);
				char *s=*b;
				s[l++]='"';
				s[l]=0;
				items[id].string=b;
				id++;
				}
				break;
			default:
				Buffer *b=new Buffer(strlen(token)+8);
				char *s=*b;
				strcpy(s,opb);
				s+=strlen(s);
				strcpy(s,token);
				char *p=s;
                s+=strlen(s);
				while(s>p){
					if(*s<=' ')
						*(s--)=0;
					else{
						break;
					}
				}
				if(*p!=0){
					if(*s!=')'){
						p=*b;
						items[id].id=TOKEN;
					}else{
						if(*opb=='-'){
							items[id].string=new Buffer("-1",3);
							items[id++].id=TOKEN;
							items[id].id=OP;
							items[id++].string=new Buffer("*",2);
							if(pr[sp].pv<13){
								sp++;
								pr[sp].pv=13;
								pr[sp].id=opid;
							}
							opid=id;
						}
						items[id].id=VAR;
					}
					items[id].string=new Buffer(p,strlen(p)+1);
					id++;
				}
				opb[0]=0;
				delete b;
			}
			if(*op){
				if(id>opid){
					int cp=Prec[whichOperator(op)];
					if(cp>pr[sp].pv){
						sp++;
						pr[sp].pv=cp;
						pr[sp].id=opid;
					}else{
						while(cp<pr[sp].pv){
							insertPush(pr[sp].id);
							items[id++].id=POP;
							sp--;
						}
						if(cp>pr[sp].pv){
							sp++;
							pr[sp].pv=cp;
							pr[sp].id=pr[sp].id;
						}			
					}
					items[id].id=OP;
					items[id++].string=new Buffer(op,strlen(op)+1);;
					opid=id;
				}else{
					strcpy(opb,op);
				}
			}
			*string=end;
			string+=l;
        }
		if(items[id-1].id==OP){
			items[id].string=new Buffer("",1);
			items[id++].id=TOKEN;
		}
		while(sp>0){
			if(pr[sp].id-1>startId){
				insertPush(pr[sp].id);
				items[id++].id=POP;
			}
			sp--;
		}
		opid=(items[startId].id==PUSH);
		while(opid){
			sp=0;
			for(int j=startId;j<id;++j){
				if(items[j].id==PUSH){
					pr[sp++].id=j;
				}
				else
					if(items[j].id==POP){
						sp--;
						if(j+1==id && pr[sp].id==startId){
							id--;
							items[startId].id=DUM;
							opid=(items[++startId].id==PUSH);
						}else
							opid=0;
					}
			}
		}
		return 1;
}

/*
int dhtmlCompiler::parseExp(char* string)
{
        char end=*string;
		int startId=id;
		PRE pr[32];
		int sp=0;
		pr[0].id=id;
		pr[0].pv=0;
		int opid=id;
		char opb[8]={0};
        while(end){
			char *token=getToken(&string);
			if(token==0){
				printf("Error in %s : %s\n",compiling,string);
				return 0;
			}
			int l=isOperator(string);
			char op[8];
			*op=0;
			if(l>0){
				if(whichOperator(string)==CMT){
					l=0;
					*string=0;
				}else{
					strncpy(op,string,l);
					op[l]=0;
				}
			}else {
				l=1;
			}
			end=*string;
			*string=0;
			switch(*token){
			case  0: 
				break;
			case '(':		
				{
					if(*opb=='-'){
						items[id].string=new Buffer("-1",3);
						items[id++].id=TOKEN;
						items[id].id=OP;
						items[id].string=new Buffer("*",2);
						if(pr[sp].pv<13){
							sp++;
							pr[sp].pv=13;
							pr[sp].id=opid;
						}
						opid=id++;
					}
//					*opb=0;
					token++;
					int pid=id;
					items[id++].id=PUSH;
					int prc=parseExp(token);
					token[strlen(token)]=')';
					if(prc>0){
						if(id-pid<3){
							id--;
							if(id!=pid){
								memcpy(&items[pid],&items[id],sizeof(Item));
								memset(&items[id],0,sizeof(Item)*(id-pid));
								id=pid+1;
							}
						}
						else{
							items[id++].id=POP;
						}
					}else
						return 0;
				}
				break;
			case '"':
				{
//				*opb=0;
				items[id].id=QUOT;*
				int l=strlen(token);
				Buffer *b=new Buffer(token,l+2);
				char *s=*b;
				s[l++]='"';
				s[l]=0;
				items[id].string=b;
				id++;
				}
				break;
			default:
				Buffer *b=new Buffer(strlen(token)+8);
				char *s=*b;
//				strcpy(s,opb);
//				s+=strlen(s);
				strcpy(s,token);
				char *p=s;
                s+=strlen(s);
				while(s>p){
					if(*s<=' ')
						*(s--)=0;
					else{
						break;
					}
				}
				if(*p!=0){
					items[id].id=(*s==')'?VAR:TOKEN);
					if(*opb){
						if(items[id].id==TOKEN){
							p=*b;
						}else{
							if(*opb=='-'){
								items[id].string=new Buffer("-1",3);
								items[id++].id=TOKEN;
								items[id].id=OP;
								items[id].string=new Buffer("*",2);
								if(pr[sp].pv<13){
									sp++;
									pr[sp].pv=13;
									pr[sp].id=opid;
								}
								opid=id++;
								items[id].id=VAR;
							}
						}
					}
					items[id].string=new Buffer(p,strlen(p)+1);
					id++;
				}
//				*opb=0;
				delete b;
			}
			if(*op){
				if(id>opid){
					int cp=Prec[whichOperator(op)];
					if(cp>pr[sp].pv){
						sp++;
						pr[sp].pv=cp;
						pr[sp].id=opid;
					}else{
						while(cp<pr[sp].pv){
							insertPush(pr[sp].id);
							items[id++].id=POP;
							sp--;
						}
						if(cp>pr[sp].pv){
							sp++;
							pr[sp].pv=cp;
							pr[sp].id=pr[sp].id;
						}			
					}
					items[id].id=OP;
					opid=id;
					items[id++].string=new Buffer(op,strlen(op)+1);;
				}else{
//					strcpy(opb,op);
				}
			}
			*string=end;
			string+=l;
        }
		if(items[id-1].id==OP){
			items[id].string=new Buffer("",1);
			items[id++].id=TOKEN;
		}
		while(sp>0){
			if(pr[sp].id-1>startId){
				insertPush(pr[sp].id);
				items[id++].id=POP;
			}
			sp--;
		}
		opid=(items[startId].id==PUSH);
		while(opid){
			sp=0;
			for(int j=startId;j<id;++j){
				if(items[j].id==PUSH){
					pr[sp++].id=j;
				}
				else
					if(items[j].id==POP){
						sp--;
						if(j+1==id && pr[sp].id==startId){
							id--;
							items[startId].id=DUM;
							opid=(items[++startId].id==PUSH);
						}else
							opid=0;
					}
			}
		}
		return 1;
}
*/

void dhtmlCompiler::putNumValue(int numAccId,double numAcc,int prec,int itype)
{
		delete items[numAccId].string;
		Buffer *p=new Buffer(64);
		char *buff=*p;
		int l;
		if (prec){
			char tmp[16];
			if(prec>0){
				snprintf(tmp,12,"%%.%df",prec);
				l=snprintf(buff,64,tmp,numAcc);
			}else{
				l=snprintf(buff,64,"%f",numAcc);
				for(;l>0;l--)
					if(buff[l]=='.')
						break;
				buff[l]=0;
			}
		}else{
			if(itype)
				l=snprintf(buff,32,"0%d",(int)numAcc);
			else
				l=snprintf(buff,32,"%d",(int)numAcc);
		}
		p->setSize(l+1);
		items[numAccId].string=p;
		items[numAccId].id=TOKEN;
}


int dhtmlCompiler::evaluate(int cid, int *err)
{
	char *divideByZero="DivideByZero";
	int syntaxError=0;
	double numAcc=0;
	int numAccId=0;
	int opid;
	int op=-1;
	int sign=0;
	int Aprec=-1;
	int itype=0;
	int bid=cid;
	for(;cid<id;++cid){
		switch(items[cid].id){
		case PUSH:	
			{
				int pid=cid;
				cid=evaluate(cid+1,err);
				if(items[pid].id==PUSH)
					op=-1;
			}       
			break;
		case POP:
			{
				int k=0,j=0;
				for(int i=bid;i<cid;++i){
					if(items[i].id!=DUM){
						k++;
						j=i;
					}
				}
				if(k<2){
					items[bid-1].id=DUM;
					items[cid].id=DUM;
					if(j>0)
						cid=j-1;
				}
			}
			goto exitA;
		case OP:
			if(op==-1){
				op=whichOperator(*items[cid].string);
				opid=cid;
			}
			else{
				sign=whichOperator(*items[cid].string);
				if(sign>2){
					syntaxError=1;
					printf("%s:syntax Error: unexpected %s\n",compiling,(char*)*items[cid].string);
					*err=1;
				}
				items[cid].id=DUM;
			}
			break;
		case TOKEN:
			{
				char* s=*items[cid].string;
				int prec;
				if(getbType(s,&prec)<2){
					int delit=1;
					double x=atof(s);
					if(sign==2)
						x*=-1;
					sign=0;
					switch(op){
					case MATCH:
						delit=0;
						break;
					case ADD:
						if(numAccId==0){
							goto startNum;
						}else
							numAcc+=x;
						break;
					case SUB:
						if(numAccId==0){
							x*=-1;
							*((char*)*items[opid].string)='+';
							goto startNum;
						}else
							numAcc-=x;
						break;
					case MUL:
						if(numAccId==0){
							goto startNum;
						}else
							numAcc*=x;
						break;
					case DIV:
						if(numAccId!=0){
							if(x!=0){
								numAcc/=x;
							}else{
								delete items[numAccId].string;
								items[numAccId].string=new Buffer(divideByZero,strlen(divideByZero)+1);
								numAccId=-1;
							}
						}
						break;
					case MOD:
						if(numAccId!=0){
							int p=(int)numAcc;
							numAcc=0;
							if(x>0){
								int z=(int)x;
								if(z>0){
									p%=z;
									numAcc=p;
								}
							}
							Aprec=0;
						}
						break;
					case EQU:
						if(numAccId!=0)
							numAcc=(numAcc==x);
						break;
					case GTE:
						if(numAccId!=0)
							numAcc=(numAcc>=x);
						break;
					case LTE:
						if(numAccId!=0)
							numAcc=(numAcc<=x);
						break;
					case NTE:
						if(numAccId!=0)
							numAcc=(numAcc!=x);
						break;
					case GT:
						if(numAccId!=0)
							numAcc=(numAcc>x);
						break;
					case LT:
						if(numAccId!=0)
							numAcc=(numAcc<x);
						break;
					case OR:
						if(numAccId!=0)
							numAcc=(numAcc||x);
						break;
					case AND:
						if(numAccId!=0)
							numAcc=(numAcc&&x);
						break;
					case -1:
						
startNum:
						itype=(*s=='0' && prec==0);
						delit=0;
						if(cid==bid)
							Aprec=prec;
						numAcc=x;
                        numAccId=cid;
					default:
						break;
					}
					if(numAccId!=0 && delit!=0){
						items[opid].id=DUM;
						items[cid].id=DUM;
					}
				}else{					
					if(numAccId!=0){
						putNumValue(numAccId,numAcc,Aprec,itype);
						Aprec=-1;
						numAccId=0;
					}
				}
			}
			op=-1;
			break;
		case QUOT:
			if(op==MATCH){
				items[cid].id=RAW;
			}
		case VAR:
			op=-1;
			if(numAccId!=0){
				putNumValue(numAccId,numAcc,Aprec,itype);
				Aprec=-1;
				numAccId=0;
			}
			break;
		}
    }
exitA:
	if(numAccId!=0){
		putNumValue(numAccId,numAcc,Aprec,itype);
	}
	return cid;
}


Buffer* recompile(File* f,SCHEDULE **newsch,Buffer **symbuff)
{
   dhtmlCompiler *tmp=new dhtmlCompiler();
   Buffer *newCode=tmp->compile(f,f->getName(),symbuff);
   *newsch=tmp->getSch();
   delete tmp;
   return newCode;
}

extern int mallocInternal;

Buffer*  dhtmlCompiler::compile(File *f,char *fname,Buffer **sym)
{
//	mallocInternal=1;
	compiling=fname;
	memset(items,0,sizeof(items));
	id=sw=bt=bp=0;
	memset(labl,0,sizeof(labl));
	int i;
	for(i=0;i<LABLS;++i){
		labl[i].jmppoint=-1;
		for(int j=0;j<LABPOINTS;++j)
			labl[i].ip[j]=-1;
	}
	ip=0;
	cjump=0;
	memset(codeBuff,0,MAXCODE*sizeof(htmlCode));
	jump[0]=0;
	readFile(f,fname);
	if(cjump>0){
		if(cjump > 0  && (jump[cjump]-codeBuff == (int)(jump[cjump]->param))){
			jump[cjump]->param=(Buffer*)ip;
			printf("Warning! No Matching ENDIF in file : %s\n",fname); 
		}
	}
	while(sw>0){
		checkSwitchEnd(0,0,1);
	}
	for(i=0;labl[i].label[0]!=0;++i){
        int jmppoint=labl[i].jmppoint-1;
		if(jmppoint<0)
			jmppoint=ip;
		int j;
		for(j=0;labl[i].ip[j]>-1;++j){
			htmlCode *code=&codeBuff[labl[i].ip[j]];
			code->param=(Buffer*)jmppoint;
		}
		if(j>0 && jmppoint==ip)
			printf("Error in file %s undefined label %s\n",fname,labl[i].label);
	}
	Buffer* codes= new Buffer(sizeof(htmlCode)*ip);
	memcpy(*codes,codeBuff,codes->getSize());
	htmlCode *cod=(htmlCode*)(char*)*codes;
	int symtotal=1;
	symbols[0]="";
	getSymbol("_event",symbols,&symtotal,1);
	getSymbol("cookie",symbols,&symtotal,1);
	for(i=0;i<ip;++i){
		cod[i].object=0;
		if((cod[i].Instruction > OBJECTCODES) && (cod[i].Instruction < JUMPCODES)){
			if(cod[i].param){
				getSymbol(*cod[i].param,symbols,&symtotal,1);
				cod[i].object=1;
			}
		}
	}
	for(i=0;i<ip;++i){
		if(cod[i].object==1){
			cod[i].object=getSymbol(*cod[i].param,symbols,&symtotal);
		}
	}
	*sym=new Buffer((char*)symbols,sizeof(char*)*symtotal);
//	mallocInternal=0;
	return codes;
}

void dhtmlCompiler::compile(File *f)
{
  char *url=f->getRealName();
  URLhandler *u=getURLhandler(url);
  if(u==0){
   Buffer *symbuf;
   Buffer *codes=compile(f,f->getName(),&symbuf);
   dhtml *nx=new dhtml(url,codes,symbuf);
   if(sch!=0){
	 sch->worker=0;
     sch->dhtml=nx;
	 nx->setScheduler(1);
     sch->next=schedules;
     schedules=sch;
     }
  }else{
	 u->refresh(f);
  }
}


void dhtmlRegisterFile(File *file)
{
	dhtmlCompiler *x=new dhtmlCompiler();
	x->compile(file);
	delete x;
}


LinkedBuffer *readLines(File *);


void dhtmlCompiler::readFile(File *fs,char* fname)
{
	miner* m = new miner();
	LinkedBuffer *f=readLines(fs);
	sch=0;
	ifcount=0;
	while(f){
		ifs=0;
		int ipp=ip;
		if(f->getType()!='c'){
			htmlCode* code = &codeBuff[ip++];
			code->Instruction=outputParam;
			code->param=*f;
		}else{
			char tmp[256];
			strncpy(tmp,*f,254);
			tmp[254]=0;
			errorString[0]=0;
			if(compile(m,*f)==0){
				printf("Error in %s : [%s]\n",fname,tmp);
				if ( strcmp(tmp,"/*")==0)
					printf("    *****  missing end of comment '<CR>*/'\n");
				else
					if ( strcmp(tmp,"*/")==0)
						printf("    ***** illegal nested comment or missing '/*<CR>'\n");
			}else{
				if(errorString[0]){
					printf("ERROR in %s, [%s] -- %s\n",fname,tmp,errorString);
				}
				if((ipp==ip) && stricmp(tmp,"endif") && strnicmp(tmp,"schedule",8) && strnicmp(tmp,"label",5) && strnicmp(tmp,"case",4) && strnicmp(tmp,"default",7)){
					printf("Error in %s: [%s]\n",fname,tmp);
				}
			}
		}
		if((cjump>0) && (ifs==0) && (ipp!=ip)){
			for(int i=cjump;i>0;i--){
				if((int)(jump[i]->param)==jump[i]-codeBuff){
					jump[i]->param=(Buffer*)(ip-1);
				}
			}
		}
		LinkedBuffer *tmp=f;
		f=f->next;
		delete tmp;
	}
	if (ifcount!=0)
		printf("Warning no matching endif(%d): [%s]\n",ifcount,fname);
	delete m;
}

int dhtmlCompiler::evaluateExp(Buffer** x,miner *n)
{
	int rc=0;
	id++;
	int newId=id;
	if(parseExp(*(*x))>0){
		int i=0;
		evaluate(newId,&i);
		if(i!=0)
			printf("%s:\n^^^ %s\n",compiling,(char*)(*(*x)));
		int j=0,k=newId;;
		for(i=newId;i<id;++i){
			if(items[i].id>OP){
				j++;
				k=i;
			}
		}
		if(j>=1){
			if(j==1){
				delete *x;
				*x=items[k].string;
				items[k].string=0;
				rc=evaluateVar(*x,n);
			}else{
				delete *x;
				if(newId>1)
					codeBuff[ip++].Instruction=pushAcc;
				for(i=newId;i<id;++i){
					switch(items[i].id){
					case DUM:
						break;
					case VAR:
						if(evaluateVar(items[i].string,n)==0){
					case TOKEN:
						codeBuff[ip].Instruction=putToken;
						codeBuff[ip++].param=items[i].string;
						}else{
							codeBuff[ip++].Instruction=putRegisterA;
						}
						items[i].string=0;
						break;
					case QUOT:
						mkString(items[i].string);
					case RAW:
						{
							codeBuff[ip].Instruction=putQuot;
							char *s=*items[i].string;
							int n=items[i].string->getSize()-2;
							s[n]=0;
							codeBuff[ip++].param=new Buffer(s+1,n);
						}
						break;		
					case OP:
						codeBuff[ip].Instruction=putOp;
						codeBuff[ip++].param=(Buffer*)whichOperator(*items[i].string);
						break;
					case PUSH:
						codeBuff[ip++].Instruction=pushAcc;
						break;
					case POP:
						codeBuff[ip++].Instruction=popAcc;
						break;
					}
				}
				if(newId==1)
					codeBuff[ip++].Instruction=moveAccToRegisterA;
				else
					codeBuff[ip++].Instruction=popAccToRegisterA;
				rc=2;
			}
		}
	}else{
		printf("%s\n^^^ %s\n",compiling,(char*)(*(*x)));
	}
	for(int i=newId;i<id;++i)
		delete items[i].string;
	id=newId-1;
	memset(items+id,0,sizeof(items)-sizeof(Item)*id);
	return rc;
}


int getNameVal(char* string, Buffer **a,Buffer **b)
{
        char *s=string;
        while(*s==' ' || *s == '\t') s++;
        if(*s==0 || *s=='"'){
			return 0;
		}
        string = s;
		char *g=0;
		char *e=0;
		while(*s){
			    if(g && *s>' ')
					return 0;
				if(isOperator(s) && *s!='-' && *s!='.')
					return 0;
                if(*s=='('){
					    e=s;
                        if(getExp(&s)==0){
                                return 0;;
                        }else
							g=s;
                }
                s++;
        }
		if(e&&g){
			s=e++;
			s--;
			while(s>string && *s<=' ')
				s--;
            s++;
            *s++=0;
			while(e<g && *e<=' ')
				e++;
			g--;
			while(g>e && *g<=' ')
				g--;
			g++;
			*g++=0;
			*a=new Buffer(string,s-string);
			if((g-e)>1)
				*b=new Buffer(e,g-e);
			else
				*b=0;
			return 1;
		}
		return 0;
}


int dhtmlCompiler::evaluateVar(Buffer* x,miner *n)
{
	htmlCode codeStack[64];
	memset(codeStack,0,sizeof(codeStack));
	int stackPtr=0;
	Buffer *a,*b;
    if(getNameVal(*x,&a,&b)==0){
		return 0;
	}
	if(b==0){ 
		delete x;
		if(strlen(*a)>0){
			htmlCode *code = &codeStack[stackPtr++];
			code->param=a;
			code->Instruction=packObjectA;
		}else
			delete a;
	}else{
		do{
			htmlCode *code = &codeStack[stackPtr++];
			code->param=a;
			code->Instruction=getValueRegister;
			delete x;
			x=b;
			if(x==0){
				code->Instruction=packObjectA;
				break;
			}
		}while(getNameVal(*x,&a,&b));
		if(x!=0){
			int i=0;
			for(char *xs=*x;*xs!=0;++xs){
				if(*xs==')')
					i--;
				else
					if(*xs=='(')
						i++;
			}
			if(i!=0){
				int j=strlen(errorString);
				if(j){
					errorString[j++]=',';
					errorString[j++]=' ';
				}
				if(i>0)
					snprintf(errorString+j,256-j,"[%s!]",(char*)*x);
				else
					snprintf(errorString+j,256-j,"[!%s]",(char*)*x);
			}
			if(stackPtr>0){
				if(evaluateExp(&x,n)==0){
					htmlCode *code = &codeBuff[ip++];
					code->param=x;
					code->Instruction=moveParamToRegisterA;
				}
			}
		}
	}
    if(stackPtr){
		for(int i=stackPtr;i>0;--i)
			memcpy(codeBuff+ip++,codeStack+i-1,sizeof(htmlCode));
		return 1;
	}
    return 0;
}



/*
int dhtmlCompiler::evaluateVar(Buffer* x,miner *n)
{
	htmlCode codeStack[32];
	int stackPtr=0;
	if(n->mine(*x,"\"*\""))
		return 0;
	Buffer *a,*b;
    if(getNameVal(*x,&a,&b)==0)
		return 0;
	if(n->mine(*x,"`*`~%(~%)~%")){ 
		delete x;
		if((x=n->getValueFinal(0))!=0){
			trim(x);
			if(strlen(*x)>0){
				htmlCode *code = &codeStack[stackPtr++];
				code->param=x;
				code->Instruction=packObjectA;
			}else
				delete x;
		}
	}else{
		Buffer *a,*b;
		while(getNameVal(*x,&a,&b)){ 
			htmlCode *code = &codeStack[stackPtr++];
			code->param=a;
			code->Instruction=getValueRegister;
			delete x;
			x=b;
		}
	while(n->mine(*x,"`*`~%(~%`*`)")){ 
			htmlCode *code = &codeStack[stackPtr++];
			if((code->param=n->getValueFinal(0))!=0)
				trim(code->param);
			code->Instruction=getValueRegister;
			delete x;
			if((x=n->getValueFinal(1))!=0){
				trim(x);
			}
		}

		char *xs=*x;
		int i;
		for(i=0;*xs!=0;++xs){
			if(*xs==')')
				i--;
			else
				if(*xs=='(')
					i++;
		}
		if(i!=0){
			int j=strlen(errorString);
			if(j){
				errorString[j++]=',';
				errorString[j++]=' ';
			}
			snprintf(errorString+j,256-j,i>0?"[%s!]":"[!%s]",(char*)*x);
		}
		if(stackPtr>0){
			htmlCode *code = &codeStack[stackPtr++];
			code->param=x;
			code->Instruction=moveParamToRegisterA;
		}
	}
    if(stackPtr){
		for(int i=stackPtr;i>0;--i)
			memcpy(codeBuff+ip++,codeStack+i-1,sizeof(htmlCode));
		return 1;
	}
    return 0;
}

*/

int dhtmlCompiler::checkLabel(Buffer* x, miner *n)
{
  if(x!=0)
	  if(n->mine(*x,"~%label%~%`*`~^")){
		  delete x;
		  Buffer* lname=n->getValueFinal(0);
		  trim(lname);
		  int i;
		  for(i=0;labl[i].label[0]!=0;++i){
			  if(stricmp(*lname,labl[i].label)==0){
				  if(labl[i].jmppoint>-1){
					  delete lname;
					  return 1;
				  }else
					  break;
			  }
		  }
		  strcpy(labl[i].label,*lname);
		  labl[i].jmppoint=ip;
		  delete lname;
		  return 1;
      }
  return 0;
}


int dhtmlCompiler::checkSleep(Buffer* x, miner *n)
{
	if(x!=0)
		if(n->mine(*x,"~%sleep%~%`#~#`~^")){
			delete x;
			int secs=atoi(n->getValue(0));
			htmlCode *code = &codeBuff[ip++];
			code->param = (Buffer*)(secs);
			code->Instruction = SleepSec;
			return 1;
		}
	return 0;
}


int dhtmlCompiler::checkLock(Buffer* x, miner *n)
{
	if(x!=0)
		if(n->mine(*x,"~%Lock~%")){
			delete x;
			htmlCode *code = &codeBuff[ip++];
			code->param = 0;
			code->Instruction = Lock;
			return 1;
		}
	return 0;
}

int dhtmlCompiler::checkRelease(Buffer* x, miner *n)
{
	if(x!=0)
		if(n->mine(*x,"~%Release~%")){
			delete x;
			htmlCode *code = &codeBuff[ip++];
			code->param = 0;
			code->Instruction = Release;
			return 1;
		}
	return 0;
}


int dhtmlCompiler::checkGoto(Buffer* x, miner *n)
{
  if(x!=0)
   if(n->mine(*x,"~%goto%~%`*`~^")){
	  delete x;
	  Buffer* lname=n->getValueFinal(0);
	  trim(lname);
	  int i,j;
	  for(i=0;labl[i].label[0]!=0;++i)
		  if(stricmp(*lname,labl[i].label)==0)
		      break;
	  strcpy(labl[i].label,*lname);
	  for(j=0;labl[i].ip[j]>-1;++j);
      labl[i].ip[j]=ip;
      htmlCode *code = &codeBuff[ip++];
      code->param = (Buffer*)-1;
      code->Instruction = jmpLabel;
	  delete lname;
      return 1;
      }
  return 0;
}


int dhtmlCompiler::checkAssignment(Buffer* x, miner *n)
{
	if(x!=0){
		if(n->mine(*x,"~%`*`~%(~%`*`)~%=~%`*`")){
			delete x;
			x=n->getValueFinal(0);
			if(x==0)
				return 1;
			trim(x);
			Buffer* name=n->getValueFinal(1);
			if(name==0)
				return 1;
			Buffer* out = n->getValueFinal(2);
			if(out==0)
				return 1;
			trim(out);
			trim(name);
			if(evaluateExp(&name,n)){
				codeBuff[ip++].Instruction=moveRegisterAtoB;
			}else{
				htmlCode *code = &codeBuff[ip++];
				code->param = name;
				code->Instruction = moveParamToRegisterB;
			}
			if(evaluateExp(&out,n)==0){
				htmlCode *code = &codeBuff[ip++];
				if(n->mine(*out,"~%\"`*`\"~%")){
					delete out;
					code->param = mkString(n->getValueFinal(0));
				}else{
					code->param=out;
				}
				code->Instruction=moveParamToRegisterA;
			}
			htmlCode* code=&codeBuff[ip++];
			code -> Instruction = putValueRegisterB;
			code -> param = x;
			return 1;
		}
	}
	return 0;
}

int dhtmlCompiler::checkDispatch(Buffer* x, miner *n)
{
	if(x!=0){
		int r=0;
		if((n->mine(*x,"~%dispatch%~%`*`")!=0) || ((r=n->mine(*x,"~%redirect%~%`*`"))!=0)){
			delete x;
			Buffer* out = n->getValueFinal(0);
			if(out==0)
				return 1;
			trim(out);
			if(evaluateExp(&out,n)==0){
				if(n->mine(*out,"~%\"`*`\"~%")){
					delete out;
					codeBuff[ip].param=mkString(n->getValueFinal(0));
				}else{
					codeBuff[ip].param = out; 
				}
				codeBuff[ip++].Instruction = moveParamToRegisterA;
			}
			htmlCode* code=&codeBuff[ip++];
			if(r==0)
				code -> Instruction=dispatch;
			else
				code -> Instruction=redirect;
			code -> param = new Buffer(sRESPONSE,RESPONSEl);
			return 1;
		}
	}
return 0;
}


int dhtmlCompiler::checkFile(Buffer* x, miner *n)
{
  if(x!=0)
  if(n->mine(*x,"~%File%~%`*`=~%`*`")){
     delete x;
     Buffer* out = n->getValueFinal(1);
     if(out==0)
        return 1;
     Buffer *tname=n->getValueFinal(0);
     if(tname==0) 
        return 1;
     trim(tname);
     if(evaluateExp(&out,n)==0){
		 htmlCode *code = &codeBuff[ip++];
		 if(n->mine(*out,"~%\"`*`\"~%")){
			 delete out;
			 code->param = n->getValueFinal(0);
		 }else
			 code->param=out;
		 code->Instruction=moveParamToRegisterA;
	 }
     htmlCode* code=&codeBuff[ip++];
     code -> Instruction = createFile;
     code -> param=tname;;
     return 1;
     }
return 0;
}

int dhtmlCompiler::checkAddition(Buffer* x, miner *n)
{
  if(x!=0)
  if(n->mine(*x,"~%`*`~%(~%`*`)~%+=`*`")){
     delete x;
     x=n->getValueFinal(0);
     if(x==0)
      return 1;
     trim(x);
     Buffer* out = n->getValueFinal(2);
     Buffer* name=n->getValueFinal(1);
     if(name==0)
        return 1;
     if(out==0)
        return 1;
     trim(out);
     trim(name);
     if(evaluateExp(&name,n)){
		 codeBuff[ip++].Instruction=moveRegisterAtoB;
	 }else{
		 htmlCode *code = &codeBuff[ip++];
		 code->param = name;
		 code->Instruction = moveParamToRegisterB;
	 }
	 if(evaluateExp(&out,n)==0){
		 htmlCode *code = &codeBuff[ip++];
		 if(n->mine(*out,"~%\"`*`\"~%")){
			 delete out;
			 code->param = mkString(n->getValueFinal(0));
		 }else
			 code->param=out;
		 code->Instruction=moveParamToRegisterA;
	 }
     htmlCode* code=&codeBuff[ip++];
     code -> Instruction = addValueRegisterB;
     code -> param = x;
     return 1;
     }
return 0;
}


int dhtmlCompiler::checkDiv(Buffer* x, miner *n)
{
  if(x!=0)
  if(n->mine(*x,"~%`*`~%(~%`*`)~%/=`*`")){
     delete x;
     x=n->getValueFinal(0);
     if(x==0)
      return 1;
     trim(x);
     Buffer* out = n->getValueFinal(2);
     Buffer* name=n->getValueFinal(1);
     if(name==0)
        return 1;
     if(out==0)
        return 1;
     trim(out);
     trim(name);
     if(evaluateExp(&name,n)){
        codeBuff[ip++].Instruction=moveRegisterAtoB;
       }else{         
          htmlCode *code = &codeBuff[ip++];
          code->param = name;
          code->Instruction = moveParamToRegisterB;
          }
	   if(evaluateExp(&out,n)==0){
		   htmlCode *code = &codeBuff[ip++];
		   if(n->mine(*out,"~%\"`*`\"~%")){
			   delete out;
			   code->param = mkString(n->getValueFinal(0));
           }else
			   code->param=out;
           code->Instruction=moveParamToRegisterA;
	   }
     htmlCode* code=&codeBuff[ip++];
     code -> Instruction = divValueRegisterB;
     code -> param = x;
     return 1;
     }
return 0;
}


int dhtmlCompiler::checkCmd(Buffer *x,miner *n)
{
	if(x!=0){
		if(n->mine(*x,"~%cmd%~%`*`=`*`(`*`)~%")){
			delete x;
			x=n->getValueFinal(2);
			Buffer *varname=n->getValueFinal(0);
			Buffer *exe=n->getValueFinal(1);
			if(exe && varname){
				trim(exe);
				trim(varname);
				if(x){
					trim(x);
					char *b=*x;
					if(*b==0 || *b==' '){
						delete x;
						x=0;
					}
				}
				INSTRUCTION i=exec;
				htmlCode *code = &codeBuff[ip++];
				if ((x==0) || evaluateExp(&x,n)==0){
					code->param=x;
					code->Instruction = moveParamToRegisterA;
					code=&codeBuff[ip++];
					i=execp;
				}
				code->param = exe;
				code->Instruction = moveParamToRegisterB;
				code = &codeBuff[ip++];
				code->param = varname; 
				code->Instruction = i;
			}
			return 1;
		}
	}
	return 0;
}



int dhtmlCompiler::checkExec(Buffer *x,miner *n)
{
	if(x!=0){
		if(n->mine(*x,"~%var%~%`*`=~%`*`.exe~%(`*`)~%") || n->mine(*x,"~%var%~%`*`=~%`*`.exe~%") ){
			delete x;
			x=n->getValueFinal(2);
			Buffer *varname=n->getValueFinal(0);
			Buffer *exe=n->getValueFinal(1);
			if(exe && varname){
				trim(varname);
				if(x){
					trim(x);
					char *b=*x;
					if(*b==0 || *b==' '){
						delete x;
						x=0;
					}
				}
				htmlCode *code = &codeBuff[ip++];
				code->param = x;
				code->Instruction = moveParamToRegisterB;
				code = &codeBuff[ip++];
				code->param = exe;
				code->Instruction = moveParamToRegisterA;
				code = &codeBuff[ip++];
				code->param = varname; 
				code->Instruction = execPrgm;
			}else{
				delete varname;
				delete x;
				delete exe;
			}
			return 1;
		}else
			if(n->mine(*x,"~%var%~%`*`=~%`*`~%")){
				delete x;
				Buffer *name=n->getValueFinal(0);
				Buffer *x=n->getValueFinal(1);
				if(evaluateExp(&x,n)==0){
					htmlCode *code = &codeBuff[ip++];
					if(n->mine(*x,"~%\"`*`\"~%")){
						delete x;
						code->param = mkString(n->getValueFinal(0));
					}else{
						code->param=x;
					}
					code->Instruction=moveParamToRegisterA;
				}
				htmlCode* code=&codeBuff[ip++];
				code -> Instruction = unpackVar;
				code -> param = name;
				return 1;
			}else
				if(n->mine(*x,"~%form%~%`*`=~%`*`~%")){
					delete x;
					Buffer *name=n->getValueFinal(0);
					Buffer *x=n->getValueFinal(1);
					if(evaluateExp(&x,n)==0){
						htmlCode *code = &codeBuff[ip++];
						if(n->mine(*x,"~%\"`*`\"~%")){
							delete x;
							code->param = mkString(n->getValueFinal(0));
						}else{
							code->param = x;
						}
						code->Instruction=moveParamToRegisterA;
					}
					htmlCode* code=&codeBuff[ip++];
					code -> Instruction = unpackForm;
					code -> param = name;
					return 1;
				}else
					if(n->mine(*x,"~%mail%~%`*`=~%`*`~%")){
						delete x;
						Buffer *name=n->getValueFinal(0);
						Buffer *x=n->getValueFinal(1);
						if(evaluateExp(&x,n)==0){
							htmlCode *code = &codeBuff[ip++];
							if(n->mine(*x,"~%\"`*`\"~%")){
								delete x;
								code->param = mkString(n->getValueFinal(0));
							}else{
								code->param=x;
							}
							code->Instruction=moveParamToRegisterA;
						}
						htmlCode* code=&codeBuff[ip++];
						code -> Instruction = unpackMail;
						code -> param = name;
						return 1;
					}else
					if(n->mine(*x,"~%email%~%`*`=~%`*`~%")){
						delete x;
						Buffer *name=n->getValueFinal(0);
						Buffer *x=n->getValueFinal(1);
						if(evaluateExp(&x,n)==0){
							htmlCode *code = &codeBuff[ip++];
							if(n->mine(*x,"~%\"`*`\"~%")){
								delete x;
								code->param = mkString(n->getValueFinal(0));
							}else{
								code->param=x;
							}
							code->Instruction=moveParamToRegisterA;
						}
						htmlCode* code=&codeBuff[ip++];
						code -> Instruction = readMail;
						code -> param = name;
						return 1;
					}
	}
	return 0;
}

int dhtmlCompiler::checkMul(Buffer* x, miner *n)
{
  if(x!=0)
  if(n->mine(*x,"~%`*`~%(~%`*`)~%\\*=`*`")){
     delete x;
     x=n->getValueFinal(0);
     if(x==0)
      return 1;
     trim(x);
     Buffer* out = n->getValueFinal(2);
     Buffer* name=n->getValueFinal(1);
     if(name==0)
        return 1;
     if(out==0)
        return 1;
     trim(out);
     trim(name);
     if(evaluateExp(&name,n)){
        codeBuff[ip++].Instruction=moveRegisterAtoB;
       }else{
          htmlCode *code = &codeBuff[ip++];
          code->param = name;
          code->Instruction = moveParamToRegisterB;
          }
     if(evaluateExp(&out,n)==0){
		 htmlCode *code = &codeBuff[ip++];
		 if(n->mine(*out,"~%\"`*`\"~%")){
			 delete out;
			 code->param = mkString(n->getValueFinal(0));
		 }else
			 code->param=out;
		 code->Instruction=moveParamToRegisterA;
	 }
     htmlCode* code=&codeBuff[ip++];
     code -> Instruction = mulValueRegisterB;
     code -> param = x;
     return 1;
     }
return 0;
}

int dhtmlCompiler::checkMod(Buffer* x, miner *n)
{
  if(x!=0)
  if(n->mine(*x,"~%`*`~%(~%`*`)~%\\%=`*`")){
     delete x;
     x=n->getValueFinal(0);
     if(x==0)
      return 1;
     trim(x);
     Buffer* out = n->getValueFinal(2);
     Buffer* name=n->getValueFinal(1);
     if(name==0)
        return 1;
     if(out==0)
        return 1;
     trim(out);
     trim(name);
     if(evaluateExp(&name,n)){
		 codeBuff[ip++].Instruction=moveRegisterAtoB;
	 }else{
		 htmlCode *code = &codeBuff[ip++];
		 code->param = name;
		 code->Instruction = moveParamToRegisterB;
	 }
     if(evaluateExp(&out,n)==0){
		 htmlCode *code = &codeBuff[ip++];
		 if(n->mine(*out,"~%\"`*`\"~%")){
			 delete out;
			 code->param = mkString(n->getValueFinal(0));
		 }else
			 code->param=out;
		 code->Instruction=moveParamToRegisterA;
	 }
     htmlCode* code=&codeBuff[ip++];
     code -> Instruction = modValueRegisterB;
     code -> param = x;
     return 1;
     }
return 0;
}



int dhtmlCompiler::checkSubstraction(Buffer* x, miner *n)
{
	if(x!=0){
		if(n->mine(*x,"~%`*`~%(~%`*`)~%-=`*`")){
			delete x;
			x=n->getValueFinal(0);
			if(x==0)
				return 1;
			trim(x);
			Buffer* out = n->getValueFinal(2);
			Buffer* name=n->getValueFinal(1);
			if(name==0)
				return 1;
			if(out==0)
				return 1;
			trim(out);
			trim(name);
			if(evaluateExp(&name,n)){
				codeBuff[ip++].Instruction=moveRegisterAtoB;
			}else{
				htmlCode *code = &codeBuff[ip++];
				code->param = name;
				code->Instruction = moveParamToRegisterB;
			}
			if(evaluateExp(&out,n)==0){
				htmlCode *code = &codeBuff[ip++];
				if(n->mine(*out,"~%\"`*`\"~%")){
					delete out;
					code->param = mkString(n->getValueFinal(0));
				}else
					code->param=out;
				code->Instruction=moveParamToRegisterA;
			}
			htmlCode* code=&codeBuff[ip++];
			code -> Instruction = subValueRegisterB;
			code -> param = x;
			return 1;
		}
	}
	return 0;
}


//<caravan>folder x="c:\\xyz"</caravan>

int dhtmlCompiler::checkFolder(Buffer* x, miner *n)
{
	if(x!=0){
		if(n->mine(*x,"~%folder%~%`*`=~%`*`")){
			delete x;
			x=n->getValueFinal(0);
			if(x==0)
				return 1;
			trim(x);
			Buffer* name=n->getValueFinal(1);
			if(name==0){
				delete x;
				return 1;
			}
			trim(name);
			if(evaluateExp(&name,n)==0){
				htmlCode *code = &codeBuff[ip++];
				if(n->mine(*name,"~%\"`*`\"~%")){
					delete name;
					code->param = n->getValueFinal(0);
				}else{
					code->param=name;
				}
				code->Instruction = moveParamToRegisterA;
			}
			htmlCode* code=&codeBuff[ip++];
			code -> Instruction = createFolder;
			code -> param = x;
			return 1;
		}
	}
	return 0;
}



//<caravan>schedule=(hour=5,6,7;minute=0,15,30,45)</caravan>


char *dys[]={"sun","mon","tue","wed","thu","fri","sat",0};
char *mnths[]={"jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec",0};

void getNumbers(int *d,char* x,int type)
{
int e=0;
d[0]=NEVER;
char tmp[16];
 for(int i=0,j=0;;++i){
    if(x[i]==',' || x[i]==0){
       int k;
       for(k=i;k>j && x[k-1]==' ';--k);
       if(k>j){
        strncpy(tmp,x+j,k-j);
        tmp[k-j]=0;
        d[e]=atoi(tmp);
        if(d[e]==0){
              if(type==MONTH){
		 int m;
                 for(m=0;m<12;++m)
                    if(strnicmp(tmp,mnths[m],3)==0)
                       break;
                    if(m<12)
                       d[e]=m+1;
                 }else
                    if(type==DAY){
		      int m;
                      for(m=0;m<7;++m)
                       if(strnicmp(tmp,dys[m],3)==0)
                         break;
                      if(m<7)
                       d[e]=m+1;
                    }else{
                        if(stricmp(tmp,"all")==0){
                         d[e=0]=ALL;
                         d[1]=NEVER;
                         break;
                         }
                        else
                         d[e]=1;
                        }
        }
        d[++e]=NEVER;
        if(e==MAXSCH)
           break;
       }
       if(x[i]==0)
          break;
       j=i+1;
       }
    }
}


int dhtmlCompiler::checkSchedule(Buffer* x, miner *n)
{
	if(x!=0)
		if(n->mine(*x,"~%schedule~%~=~%(`*`)")){
			delete x;
			if(sch==0){
				Buffer* sb = new Buffer(sizeof(SCHEDULE));
				sch=(SCHEDULE*)((char*)*sb);
				sch->deleteThis=sb;
				sch->dhtml=0;
			}else{
				return 1;
			}
			SCHEDULE *s=sch;
			s->count=ALL;
			s->sch[YEAR][0]=NEVER;
			s->sch[MONTH][0]=NEVER;
			s->sch[DATE][0]=NEVER;
			s->sch[DAY][0]=ALL;
			s->sch[HOUR][0]=NEVER;
			s->sch[MINUTE][0]=NEVER;
			s->sch[YEAR][1]=NEVER;
			s->sch[MONTH][1]=NEVER;
			s->sch[DATE][1]=NEVER;
			s->sch[DAY][1]=NEVER;
			s->sch[HOUR][1]=NEVER;
			s->sch[MINUTE][1]=NEVER;
			Buffer* x=n->getValueFinal(0);
			while(x!=0){
				Buffer* t;
				Buffer* z;
				if(n->mine(*x,"~%`*`~%=~%`*`\\&~%`*`")){
					delete x;
					x=n->getValueFinal(2);
getlast:
					t=n->getValueFinal(0);
					z=n->getValueFinal(1);
					if(t&&z){
						if(stricmp(*t,"year")==0){
							if(s->sch[YEAR][0]<0){
								getNumbers(s->sch[YEAR],*z,YEAR);
								int i;
								for(i=0;s->sch[YEAR][i]!=NEVER;++i)
									s->sch[YEAR][i]=s->sch[YEAR][i]%100+2000;
								if(i!=0){
									if(s->sch[MONTH][0]==NEVER)
										s->sch[MONTH][0]=1;
									if(s->sch[DATE][0]==NEVER)
										s->sch[DATE][0]=1;
									if(s->sch[HOUR][0]==NEVER)
										s->sch[HOUR][0]=0;
									if(s->sch[MINUTE][0]==NEVER)
										s->sch[MINUTE][0]=0;
								}
							}
						}else
							if(stricmp(*t,"month")==0){
								if(s->sch[MONTH][0]<=1){
									getNumbers(s->sch[MONTH],*z,MONTH);
									int i;
									for(i=0;s->sch[MONTH][i]!=NEVER;++i)
										s->sch[MONTH][i]=s->sch[MONTH][i]%12;
									if(i!=0){
										if(s->sch[YEAR][0]==NEVER)
											s->sch[YEAR][0]=ALL;
										if(s->sch[DATE][0]==NEVER)
											s->sch[DATE][0]=1;
										if(s->sch[HOUR][0]==NEVER)
											s->sch[HOUR][0]=0;
										if(s->sch[MINUTE][0]==NEVER)
											s->sch[MINUTE][0]=0;
									}
								}
							}else
								if(stricmp(*t,"day")==0){
									if(s->sch[DAY][0]<0){
										getNumbers(s->sch[DAY],*z,DAY);
										int i;
										for(i=0;s->sch[DAY][i]!=NEVER;++i)
											s->sch[DAY][i]=s->sch[DAY][i]%7;
										if(i!=0){
											if(s->sch[YEAR][0]==NEVER)
												s->sch[YEAR][0]=ALL;
											if(s->sch[MONTH][0]==NEVER)
												s->sch[MONTH][0]=ALL;
											if(s->sch[DATE][0]==NEVER)
												s->sch[DATE][0]=ALL;
											if(s->sch[HOUR][0]==NEVER)
												s->sch[HOUR][0]=0;
											if(s->sch[MINUTE][0]==NEVER)
												s->sch[MINUTE][0]=0;
										}
									}
								}else
									if(stricmp(*t,"date")==0){
										if(s->sch[DATE][0]<=1){
											getNumbers(s->sch[DATE],*z,DATE);
											int i;
											for(i=0;s->sch[DATE][i]!=NEVER;++i)
												s->sch[DATE][i]=s->sch[DATE][i]%31;
											if(i!=0){
												if(s->sch[YEAR][0]==NEVER)
													s->sch[YEAR][0]=ALL;
												if(s->sch[MONTH][0]==NEVER)
													s->sch[MONTH][0]=ALL;
												if(s->sch[HOUR][0]==NEVER)
													s->sch[HOUR][0]=0;
												if(s->sch[MINUTE][0]==NEVER)
													s->sch[MINUTE][0]=0;
											}
										}
									}else
										if(stricmp(*t,"hour")==0){
											if(s->sch[HOUR][0]<=0){
												getNumbers(s->sch[HOUR],*z,HOUR);
												int i;
												for(i=0;s->sch[HOUR][i]!=NEVER;++i)
													s->sch[HOUR][i]=s->sch[HOUR][i]%24;
												if(i!=0){
													if(s->sch[YEAR][0]==NEVER)
														s->sch[YEAR][0]=ALL;
													if(s->sch[MONTH][0]==NEVER)
														s->sch[MONTH][0]=ALL;                        
													if(s->sch[DATE][0]==NEVER)
														s->sch[DATE][0]=ALL;
													if(s->sch[MINUTE][0]==NEVER)
														s->sch[MINUTE][0]=0;
												}
											}
										}else
											if(stricmp(*t,"minute")==0){
												if(s->sch[MINUTE][0]<=0){
													getNumbers(s->sch[MINUTE],*z,MINUTE);
													int i;
													for(i=0;s->sch[MINUTE][i]!=NEVER;++i)
														s->sch[MINUTE][i]=s->sch[MINUTE][i]%60;
													if(i!=0){
														if(s->sch[YEAR][0]==NEVER)
															s->sch[YEAR][0]=ALL;
														if(s->sch[MONTH][0]==NEVER)
															s->sch[MONTH][0]=ALL;                        
														if(s->sch[DATE][0]==NEVER)
															s->sch[DATE][0]=ALL;
														if(s->sch[HOUR][0]==NEVER)
															s->sch[HOUR][0]=ALL;
													}
												}
											}else
												if(stricmp(*t,"count")==0){
													if(s->count==ALL){
														s->count=atoi(*z);
													}
												}
              }
           }else{
			   if(n->mine(*x,"`*`=~%`*`")){
				   delete x;
				   x=0;
				   goto getlast;
			   }else{
				   delete x;
				   x=0;
			   }
		   }
        }
		return 1;
     }
	 return 0;
}



int dhtmlCompiler::checkSwitch(Buffer* x, miner *n)
{
	if(x!=0){
		if(n->mine(*x,"~%switch%~%`*`") || n->mine(*x,"~%switch~%(`*`)")){
			delete x;
			Buffer* out=n->getValueFinal(0);
			if(out==0)
				return 1;
			trim(out);
			if(evaluateExp(&out,n)==0){
				htmlCode *code = &codeBuff[ip++];
				if(n->mine(*out,"~%\"`*`\"~%")){
					delete out;
					code->param = n->getValueFinal(0);
				}else{
					code->param = out;
				}
				code->Instruction=moveParamToRegisterA;
			}
			sw++;
			bt++;
			swpt[sw].elements=0;
			swpt[sw].swstart=ip;
			swpt[sw].defaultIp=0;
			swpt[sw].elementBuffer=new Buffer(sizeof(Buffer*)*32);
			swpt[sw].cases=(Buffer**)((char*)*swpt[sw].elementBuffer);
			codeBuff[ip++].Instruction=sjmp;
			return 1;
		}
	}
	return 0;
}

int dhtmlCompiler::checkCase(Buffer* x, miner *n)
{
	if(x!=0){
		if((sw>0) && n->mine(*x,"~%case%~%`*`:~%")){
			Buffer *b=n->getValueFinal(0);
			trim(b);
			if(n->mine(*b,"~%\"`*`\"~%")){
				delete b;
				b = mkString(n->getValueFinal(0));
			}
			int n=b->getSize();
			for(int i=0;i<swpt[sw].elements;++i){
				if(memicmp(*swpt[sw].cases[i],*b,n)==0){
					delete b;
				    return 0;
				}
			}
			delete x;
			Buffer *p=new Buffer(n+sizeof(int));
			char *s=*p;
			memcpy(s,(char*)*b,b->getSize());
			s+=n;
			*((int*)s)=ip-1;
			p->setSize(n);
			if((ULONG)swpt[sw].elementBuffer->getSize()<=swpt[sw].elements*sizeof(Buffer*)){
				Buffer *tmp=new Buffer(sizeof(Buffer*)*(swpt[sw].elements+32));
				memcpy(*tmp,swpt[sw].cases,sizeof(Buffer*)*swpt[sw].elements);
				swpt[sw].cases=(Buffer**)((char*)*tmp);
				delete swpt[sw].elementBuffer;
				swpt[sw].elementBuffer=tmp;
			}
			swpt[sw].cases[swpt[sw].elements++]=p;
			delete b;
			return 1;
		}
	}
	return 0;
}

int dhtmlCompiler::checkDefault(Buffer* x, miner *n)
{
	if(x!=0){
		if((sw>0)  && n->mine(*x,"~%default~%:~%")){
			delete x;
			swpt[sw].defaultIp=ip-1;
			return 1;
		}
	}
	return 0;
}

int dhtmlCompiler::checkSwitchEnd(Buffer* x, miner *n,int fin)
{
	if(fin || (n->mine(*x,"~%endSwitch~%") && (sw>0))){
			delete x;
			int cip=ip;
			codeBuff[ip].Instruction=sjmp;
			codeBuff[swpt[sw].swstart].param=(Buffer*)ip++;
			for(int i=0;i<swpt[sw].elements;++i){
				codeBuff[ip].param=swpt[sw].cases[i];
				codeBuff[ip++].Instruction=switchCase;
			}
			if(swpt[sw].defaultIp!=0){
				codeBuff[ip].Instruction=sjmp;
				codeBuff[ip++].param=(Buffer*)swpt[sw].defaultIp;
			}
			codeBuff[cip].param=(Buffer*)(ip-1);
			delete swpt[sw].elementBuffer;
			sw--;
			adjustBreaks();
			return 1;
	}
	return 0;
}




int dhtmlCompiler::checkIfDomain(Buffer* x, miner *n)
{
	if(x!=0){
		if(n->mine(*x,"~%domain%~%`*`")){
			delete x;
			Buffer* out=n->getValueFinal(0);
			if(out==0)
				return 1;
			trim(out);
			if(evaluateExp(&out,n)==0){
				htmlCode *code = &codeBuff[ip++];
				if(n->mine(*out,"~%\"`*`\"~%")){
					delete out;
					if((code->param = n->getValueFinal(0))!=0)
						trim(code->param);
				}else{
					code->param = out;
				}
				code->Instruction=moveParamToRegisterA;
			}
			codeBuff[ip].param=new Buffer(sUSERINFO,9);
			codeBuff[ip++].Instruction = domainCheck;
			return 1;
		}
	}
	return 0;
}



int dhtmlCompiler::makeElse()
{
	if(cjump>0){
		if(jump[cjump]->Instruction==ejmp){
			if(jump[cjump]->param==(Buffer*)(jump[cjump]-codeBuff))
				jump[cjump]->param=(Buffer*)(ip-1);
			cjump--;
		}
		if(cjump>0 && jump[cjump]->Instruction!=ejmp){
			Buffer* tip=jump[cjump]->param;
			jump[cjump]->param=(Buffer*)(ip);
			if(cjump>1 && jump[cjump-1]->Instruction==sjmp){
				jump[--cjump]->param=(Buffer*)(ip-1);
			}
			jump[cjump]=&codeBuff[ip];
			jump[cjump] -> Instruction = ejmp;
			jump[cjump] -> param=(Buffer*)ip++;
			for(int i=cjump-1;i>0;--i)
				if(jump[i]->param==tip)
					jump[i]->param=(Buffer*)(jump[i]-codeBuff);
			return 1;
		}
	}
	return 0;
}


int dhtmlCompiler::makeElseIf()
{
	if(cjump>0){
		if(cjump>0 && jump[cjump]->Instruction!=ejmp){
			Buffer* tip=jump[cjump]->param;
			jump[cjump]->param=(Buffer*)(ip);
			if(cjump>1 && jump[cjump-1]->Instruction==sjmp)
				jump[--cjump]->param=(Buffer*)(ip-1);
			jump[cjump]=&codeBuff[ip];
			jump[cjump] -> Instruction = sjmp;
			jump[cjump] -> param=(Buffer*)ip++;
			for(int i=cjump-1;i>0;--i){
				if(jump[i]->param==tip)
					jump[i]->param=(Buffer*)(jump[i]-codeBuff);
			}
			return 1;
		}
	}
	return 0;
}

#define CHECKELSEIF if (elseif!=0){ if (makeElseIf()==0) return 1;}


int dhtmlCompiler::checkElse(Buffer* x, miner *n)
{

	if(x!=0){
		if(n->mine(*x,"~%else~%")){
			ifs=1;
			delete x;
			makeElse();
			return 1;
		}
	}
	return 0;
}

int dhtmlCompiler::checkEndIf(Buffer* x, miner *n)
{
	if(x!=0){
		if(n->mine(*x,"~%endif~%")){
			delete x;
			if(cjump>0){
				ifcount--;
				Buffer* tip=jump[cjump]->param;
				for(int i=cjump;i>0;--i)
					if(jump[i]->param==tip || jump[i]->param==(Buffer*)(jump[i]-codeBuff))
						jump[i]->param=(Buffer*)(ip-1);
					else
						break;
				if(jump[cjump--]->Instruction!=ejmp)
					if(cjump>0 && jump[cjump]->Instruction==sjmp)
						cjump--;
			}
			return 1;
		}
	}
	return 0;
}



#define MAKEJUMP(jmpCnd)jump[++cjump] = &codeBuff[ip];jump[cjump] -> param=(Buffer*)ip++;jump[cjump] -> Instruction = jmpCnd;ifs=1;

int dhtmlCompiler::checkIfTrue(Buffer* x, miner *n)
{
	if(x!=0){
		int elseif=0;
		if(n->mine(*x,"~%if%`*`") || ((elseif=n->mine(*x,"~%elseif%`*`"))!=0) || 
			n->mine(*x,"~%if`(*`") || ((elseif=n->mine(*x,"~%elseif`(*`"))!=0)){
			delete x;
			CHECKELSEIF;
			if(elseif==0)
				ifcount++;
			Buffer* exp=n->getValueFinal(0);
			if(exp==0)
				return 1;
			trim(exp);
			switch(evaluateExp(&exp,n)){
			case 0:
				{
					codeBuff[ip].param=exp;;
					int n;
					if(getbType(*exp,&n)<2){
						codeBuff[ip++].Instruction = putToken;
			case 2:
						MAKEJUMP(jmpIfNotTrue);
						break;
					}
					else
						codeBuff[ip++].Instruction=chkIfObjZero;
				}
			case 1:
				MAKEJUMP(jmpIfValueZero);
				break;
			}
			return 1;
		}
	}
	return 0;
}

int breakString(char *string)
{
	int q=0;
	int b=0;
	char *c=string;
	while(*string){
		if(*string=='='){
			if(q==0 && b==0){
				return string-c;
			}
		}else
		if(*string=='"'){
			if(q==0)
				q++;
			else
				q--;
		}else
			if((*string=='(') && (q==0)){
				b++;
			}else
				if((*string==')') && (q==0)){
					b--;
				}else
					if(*string=='\\'){
						string++;
						if(*string==0)
							return 0;
					}
	string++;
	}
	return 0;
}


int dhtmlCompiler::checkSubstitute(Buffer* x,miner *n)
{
	if(x!=0){
		if(n->mine(*x,"~%filter%~%`*`") || n->mine(*x,"~%mode%~%`*`")){
			char *c=n->getValue(0);
			int q;
			if((q=breakString(c))!=0){
				delete x;				
				htmlCode* code;
				c[q]=0;
				Buffer *p=new Buffer(c,q+1);
				Buffer *s=new Buffer(c+q+1,strlen(c+q+1)+1);
				trim(s);
				trim(p);
				if(evaluateExp(&s,n)==0){
					code=&codeBuff[ip++];
					if(n->mine(*s,"\"`*`\"")){
						delete s;
						code->param=mkString(n->getValueFinal(0));
					}else{
						code->param=s;
					}
					code->Instruction=moveParamToRegisterB;
				}else{
					codeBuff[ip++].Instruction=moveRegisterAtoB;
				}	
				if(evaluateExp(&p,n)==0){
					code=&codeBuff[ip++];
					if(n->mine(*p,"\"`*`\"")){
						delete p;
						code->param=mkString(n->getValueFinal(0));
					}else{
						code->param=p;
					}
					code->Instruction=moveParamToRegisterA;
				}
				codeBuff[ip++].Instruction = substituteString;
				return 1;
			}
		}
	}
	return 0;
}

/*
int dhtmlCompiler::checkSubstitute(Buffer* x,miner *n)
{
	if(x!=0){
		int q=0;
		if(((q=n->mine(*x,"~%filter%~%\"`*`\"~%=`*`"))!=0) || n->mine(*x,"~%filter%~%`*`=`*`") || n->mine(*x,"~%mode%~%`*`=`*`")){
				delete x;
				htmlCode* code;
				Buffer *s=n->getValueFinal(1);
				Buffer *p=n->getValueFinal(0);
				trim(s);
				trim(p);
				if(evaluateExp(&s,n)==0){
					code=&codeBuff[ip++];
					if(n->mine(*s,"\"`*`\"")){
						delete s;
						code->param=mkString(n->getValueFinal(0));
					}else{
						code->param=s;
					}
					code->Instruction=moveParamToRegisterB;
				}else{
					codeBuff[ip++].Instruction=moveRegisterAtoB;
				}	
				if(q || (evaluateExp(&p,n)==0)){
					code=&codeBuff[ip++];
					if(n->mine(*p,"\"`*`\"")){
						delete p;
						code->param=mkString(n->getValueFinal(0));
					}else{
						code->param=(q?mkString(p):p);
					}
					code->Instruction=moveParamToRegisterA;
				}
				codeBuff[ip++].Instruction = substituteString;
				return 1;
			}
	}
	return 0;
}
*/

int dhtmlCompiler::checkString(Buffer* x,miner *n)
{
  if(x!=0)
  if(n->mine(*x,"\"`*`\"")){
   delete x;
   Buffer* name=mkString(n->getValueFinal(0));
   htmlCode* code=&codeBuff[ip++];
   code -> Instruction = outputParam;
   code->param=name;
   return 1;
   }
return 0;
}



int dhtmlCompiler::checkOver(Buffer* x, miner *n)
{
  if(x!=0)
  if(n->mine(*x,"~%over~%")){
     delete x;
     codeBuff[ip++].Instruction = quit;
     return 1;
     }

return 0;
}

int dhtmlCompiler::checkQuitLoops(Buffer* x, miner *n)
{
  if(x!=0)
  if(n->mine(*x,"~%endloops~%")){
     delete x;
     codeBuff[ip++].Instruction = quitLoops;
     return 1;
     }
  return 0;
}

int dhtmlCompiler::checkSuspend(Buffer* x, miner *n)
{
  if(x!=0)
  if(n->mine(*x,"~%suspend~%")){
     delete x;
     codeBuff[ip++].Instruction = suspend;
     return 1;
     }
return 0;
}




int dhtmlCompiler::checkMode(Buffer* x, miner *n)
{
	if(x!=0)
		if(n->mine(*x,"~%mode%~%`*`~%") || n->mine(*x,"~%filter%~%`*`~%")){
			delete x;
			Buffer* s=n->getValueFinal(0);
			if(evaluateExp(&s,n)==0){
				if(n->mine(*s,"\"`*`\"")){
					delete s;
					s=n->getValueFinal(0);
				}
				codeBuff[ip].Instruction=setMode;
				codeBuff[ip++].param=s;
			}else{
				codeBuff[ip++].Instruction=setModeReg;
			}
			return 1;
		}
		return 0;
}



int dhtmlCompiler::checkVar(Buffer* x, miner *n)
{
	if(n->mine(*x,"~%VAR%~%*~%=*")){
		if(n->mine(*x,"~%VAR%~%`*`~%=~%{`*`}~%X~%{`*`}~%:~%{`*`}~%")){
			delete x;
			Buffer *a=n->getValueFinal(3);
			Buffer *b=n->getValueFinal(2);
			trim(b);
			Buffer *c=n->getValueFinal(1);
			trim(c);
			Buffer *d=n->getValueFinal(0);
			trim(d);
			int eb=1;
			int ec=1;
			if(a && b && c && d){
				char* s=*b;
				int l=b->getSize()-1;
				if(*s=='"' && l>0 && s[l-1]=='"'){
					if(l-1 > 0 && s[l-2]=='\\');
					else{
						s[--l]=0;
						s++;
						Buffer *tmp=new Buffer(s,l);
						delete b;
						b=tmp;
					}
					eb=0;
				}
				s=*c;
				l=c->getSize()-1;
				if(*s=='"' && l>0 && s[l-1]=='"'){
					if(l-1 > 0 && s[l-2]=='\\');
					else{
						s[--l]=0;
						s++;
						Buffer *tmp=new Buffer(s,l);
						delete c;
						c=tmp;
					}
					ec=0;
				}
				trim(a);
				if(evaluateExp(&a,n)==0){
					htmlCode *code = &codeBuff[ip++];
					code->param = a;
					code->Instruction = moveParamToRegisterC;
				}else{
					codeBuff[ip++].Instruction=moveRegisterAtoC;
				}
				if((eb==0) || (evaluateExp(&b,n)==0)){
					htmlCode *code = &codeBuff[ip++];
					code->param = b;
					code->Instruction = moveParamToRegisterB;
				}else{
					codeBuff[ip++].Instruction=moveRegisterAtoB;
				}
				if((ec==0) || (evaluateExp(&c,n)==0)){
					htmlCode *code = &codeBuff[ip++];
					code->param = c;
					code->Instruction = moveParamToRegisterA;
				}
				codeBuff[ip].Instruction=createParser;
				codeBuff[ip++].param=d;
			}
			return 1;
		}
	}else
		if(n->mine(*x,"~%VAR%~%`*`~%")){ 
			delete x;
			codeBuff[ip].Instruction=createVar;
			codeBuff[ip++].param=n->getValueFinal(0);
			return 1;
		}else
		if(n->mine(*x,"~%search%~%`*`~%")){ 
			delete x;
			codeBuff[ip].Instruction=createSearch;
			codeBuff[ip++].param=n->getValueFinal(0);
			return 1;
		}

	return(0);
}



int dhtmlCompiler::checkForm(Buffer* x, miner *n)
{
   if(n->mine(*x,"~%Form%~%`*`~%")){ 
      delete x;
      codeBuff[ip].Instruction=createForm;
      codeBuff[ip++].param=n->getValueFinal(0);
      return 1;
      }
   return(0);
}

int dhtmlCompiler::checkMail(Buffer* x, miner *n)
{
   if(n->mine(*x,"~%Mail%~%`*`~%")){ 
      delete x;
      codeBuff[ip].Instruction=createMail;
      codeBuff[ip++].param=n->getValueFinal(0);
      return 1;
      }
   return(0);
}


int dhtmlCompiler::checkUser(Buffer* x, miner *n)
{
   if(n->mine(*x,"~%USER%~%`*`~%")){ 
      delete x;
      codeBuff[ip].Instruction=createUser;
      codeBuff[ip++].param=n->getValueFinal(0);
      return 1;
      }
   return(0);
}

int dhtmlCompiler::checkHost(Buffer* x, miner *n)
{
   if(n->mine(*x,"~%HOST%~%`*`~%=~%`*`")){ 
      delete x;
      x=n->getValueFinal(1);
      Buffer *parm=n->getValueFinal(0);
      if(evaluateExp(&x,n)==0){
		  htmlCode *code = &codeBuff[ip++];
		  if(n->mine(*x,"~%\"`*`\"~%")){
			  code->param = mkString(n->getValueFinal(0));
			  delete x;
		  }else 
			  code->param=x;
		  code->Instruction=moveParamToRegisterA;
	  }
      codeBuff[ip].Instruction=createHost;
      codeBuff[ip++].param=parm;
      return 1;
      }
   return(0);
}


int dhtmlCompiler::checkFTP(Buffer* x, miner *n)
{
	if(n->mine(*x,"~%FTP%~%`*`~%=~%`*`")){ 
		delete x;
		x=n->getValueFinal(1);
		Buffer *parm=n->getValueFinal(0);
		if(evaluateExp(&x,n)==0){
			htmlCode *code = &codeBuff[ip++];
			if(n->mine(*x,"~%\"`*`\"~%")){
				delete x;
				code->param = mkString(n->getValueFinal(0));
			}else
				code->param=x;
			code->Instruction=moveParamToRegisterA;
        }
		codeBuff[ip].Instruction=createFTP;
		codeBuff[ip++].param=parm;
		return 1;
	}
	return(0);
}



int dhtmlCompiler::checkTime(Buffer* x, miner *n)
{
   if(n->mine(*x,"~%Time%~%`*`~%")){ 
      delete x;
      codeBuff[ip].Instruction=createTime;
      codeBuff[ip++].param=n->getValueFinal(0);
      return 1;
      }
   return(0);
}

int dhtmlCompiler::checkInclude(Buffer* x, miner *n)
{
	if(n->mine(*x,"~%include%~%`*`~%")){ 
		delete x;
		Buffer *b=n->getValueFinal(0);
		if(b==0)
			return 1;
		if(evaluateExp(&b,n)==0){
			rmQuotes(b,n);
			htmlCode *code=&codeBuff[ip++];
			code->param=b;
			code->Instruction=includeFile;
		}else
			codeBuff[ip++].Instruction=includeFileRegister;
		return 1;
	}
	return(0);
}



int dhtmlCompiler::checkLoopStart(Buffer* x, miner *n)
{
   if(x!=0)
   if(n->mine(*x,"~%LOOP%~%`*`%`*`")){
	delete x;
    Buffer *b=n->getValueFinal(1);
    Buffer *name=n->getValueFinal(0);
    if(b) trim(b);
    if(evaluateExp(&b,n)==0){
      codeBuff[ip].Instruction=moveParamToRegisterA;
      codeBuff[ip].param = b;
      ip++;
      }
    codeBuff[ip].Instruction = loopStart;
    codeBuff[ip++].param=name;
	bt++;
	putBreak();
    return 1;
    }
   return 0;
}

void dhtmlCompiler::putBreak()
{
	bp++;
	breaks[bp].id=bt;
	breaks[bp].ip=ip;
	codeBuff[ip++].Instruction=sjmp;
}

int dhtmlCompiler::checkBreak(Buffer* x, miner *n)
{
  if((bt > 0) && (n->mine(*x,"~%break~%"))){
		  delete x;
		  putBreak();
		  return 1;
  }
  return 0;
}

void dhtmlCompiler:: adjustBreaks()
{
	while((bp>0) && (breaks[bp].id==bt)){
		codeBuff[breaks[bp].ip].param=(Buffer*)(ip-1);
		bp--;
	}
	bt--;
}

int dhtmlCompiler::checkLoopEnd(Buffer* x, miner *n)
{
   if(x!=0)
   if(n->mine(*x,"~%REPEAT%~%`*`%~%`~#`") || n->mine(*x,"~%REPEAT%`*`")){
	  delete x;
      htmlCode* code=&codeBuff[ip++];
      code->Instruction=moveParamToRegisterA;
      code->param=n->getValueFinal(1);
      code=&codeBuff[ip++];
      code->Instruction=repeatLoop;
	  Buffer *loopName=n->getValueFinal(0);
	  trim(loopName);
      code->param=loopName;
	  adjustBreaks();
      code=&codeBuff[ip++];
      code->Instruction=rmLoop;
      code->param=0;
	  return(1);
      }
   return 0;
}


int dhtmlCompiler::checkOutput(Buffer* x, miner *n)
{
	if(x!=0){
		int append=0;
		if(n->mine(*x,"~%OUTPUT%~%\"`*`\"") || ((append=n->mine(*x,"~%APPEND%~%\"`*`\""))!=0) ){
			delete x;
			Buffer *name=n->getValueFinal(0);
			if(name){ 
				trim (name);
				rmQuotes(name,n);
				codeBuff[ip].Instruction=moveParamToRegisterA;
				codeBuff[ip++].param = name;
				if(append)
					codeBuff[ip++].Instruction = appendToFile;
				else
					codeBuff[ip++].Instruction = writeToFile;
			}
			return 1;
		}else
			if(n->mine(*x,"~%OUTPUT%~%`*`") || ((append=n->mine(*x,"~%append%~%`*`"))!=0)){
				delete x;
				Buffer *name=n->getValueFinal(0);
				if(name){ 
					trim (name);
					if(evaluateExp(&name,n)==0){
						if(append)
							codeBuff[ip].Instruction=appendToFileObj;
						else
							codeBuff[ip].Instruction=writeToFileObj;
						codeBuff[ip++].param = name;
					}else{
						if(append)
							codeBuff[ip++].Instruction = appendToFile;
						else
							codeBuff[ip++].Instruction = writeToFile;
					}
				}
				return 1;
			}
	}
	return 0;
}




int dhtmlCompiler::checkDelete(Buffer* x, miner *n)
{
   if(x!=0)
   if(n->mine(*x,"~%Delete%~%`*`")){
	delete x;
    Buffer *name=n->getValueFinal(0);
    if(name) trim (name);
    codeBuff[ip].Instruction=deleteObject;
    codeBuff[ip++].param = name;
    return 1;
    }
   return 0;
}


int dhtmlCompiler::checkRegister(Buffer* x, miner *n)
{
	if(x!=0)
		if(n->mine(*x,"~%Compile%~%`*`")){
			delete x;
			Buffer *name=n->getValueFinal(0);
			if(name){
				codeBuff[ip].param = new Buffer("admin",6);;
				codeBuff[ip++].Instruction=moveParamToRegisterA;
				codeBuff[ip].param=new Buffer(sUSERINFO,9);
				codeBuff[ip++].Instruction = adminCheck;
				rmQuotes(name,n);
				codeBuff[ip].param = name;
				codeBuff[ip++].Instruction=registerFile;
				return 1;
			}
		}
		return 0;
}


int dhtmlCompiler::checkFlush(Buffer* x, miner *n)
{
   if(x!=0)
   if(n->mine(*x,"~%Flush%~%Data")){
	delete x;
    codeBuff[ip].Instruction=flushData;
    codeBuff[ip++].param = 0;
    return 1;
    }
   return 0;
}



int dhtmlCompiler::checkRebuild(Buffer* x, miner *n)
{
   if(x!=0)
   if(n->mine(*x,"~%rebuild*")){
	delete x;
    codeBuff[ip].Instruction=rebuild;
    codeBuff[ip++].param = 0;
    return 1;
    }
   return 0;
}

int dhtmlCompiler::checkObject(Buffer* x,miner *n)
{
	if(n->mine(*x,"~%object%~%`*`=`*`")){
		delete x;
		Buffer *name=n->getValueFinal(0);
		Buffer *file=n->getValueFinal(1);
		trim(name);
		trim(file);
		if(evaluateExp(&file,n)==0){
			mkString(file);
			rmQuotes(file,n);
			codeBuff[ip].Instruction=moveParamToRegisterA;
			codeBuff[ip++].param = file;
		}
        codeBuff[ip].param=name;
        codeBuff[ip++].Instruction=createObjectFromFile;
        return 1;
	}else{
		if(n->mine(*x,"~%object%~%`*`")){
			delete x;
			trim(codeBuff[ip].param=n->getValueFinal(0));
			codeBuff[ip++].Instruction=createObject;
			return 1;
		}
	}
	return 0;
}


int dhtmlCompiler::checkQueue(Buffer* x,miner *n)
{
	if(n->mine(*x,"~%queue%~%`*`(~%`*`,~%`*`)") || n->mine(*x,"~%queue%~%`*`(~%`*`)")){
		delete x;
		Buffer *name=n->getValueFinal(0);
		Buffer *type=n->getValueFinal(1);
		Buffer *domain=n->getValueFinal(2);
		trim(name);
		trim(type);
		if(domain){
			trim(domain);
			if(evaluateExp(&domain,n)==0){
				codeBuff[ip].Instruction=moveParamToRegisterB;
				codeBuff[ip++].param = domain;
			}else
				codeBuff[ip++].Instruction=moveRegisterAtoB;
		}
		if(evaluateExp(&type,n)==0){
			codeBuff[ip].Instruction=moveParamToRegisterA;
			codeBuff[ip++].param = type;
		}
        codeBuff[ip].param=name;
        codeBuff[ip++].Instruction=createQueue;
        return 1;
	}
	return 0;
}



int dhtmlCompiler::checkEventHandler(Buffer* x,miner *n)
{
	if(n->mine(*x,"~%eventHandler~%(~%`*`,~%`*`)") || n->mine(*x,"~%eventHandler~%(~%`*`)")){
		delete x;
		if(sch==0){
			Buffer* sb = new Buffer(sizeof(SCHEDULE));
			sch=(SCHEDULE*)((char*)*sb);
			sch->deleteThis=sb;
			sch->dhtml=0;
		}else{
			return 1;
		}
		SCHEDULE *s=sch;
		s->count=1;
		s->sch[YEAR][0]=ALL;
		s->sch[MONTH][0]=ALL;
		s->sch[DATE][0]=ALL;
		s->sch[DAY][0]=ALL;
		s->sch[HOUR][0]=ALL;
		s->sch[MINUTE][0]=ALL;
		s->sch[YEAR][1]=NEVER;
		s->sch[MONTH][1]=NEVER;
		s->sch[DATE][1]=NEVER;
		s->sch[DAY][1]=NEVER;
		s->sch[HOUR][1]=NEVER;
		s->sch[MINUTE][1]=NEVER;
		Buffer *type=n->getValueFinal(0);
		Buffer *domain=n->getValueFinal(1);
		trim(type);
		if(domain){
			trim(domain);
			if(evaluateExp(&domain,n)==0){
				codeBuff[ip].Instruction=moveParamToRegisterB;
				codeBuff[ip++].param = domain;
			}else
				codeBuff[ip++].Instruction=moveRegisterAtoB;
		}
		if(evaluateExp(&type,n)==0){
			codeBuff[ip].Instruction=moveParamToRegisterA;
			codeBuff[ip++].param = type;
		}
        codeBuff[ip].param=0;
        codeBuff[ip++].Instruction=eventHandler;
        codeBuff[ip].param=new Buffer("_event",7);
		codeBuff[ip++].Instruction=checkIfEventHandler;
		return 1;
	}
	return 0;
}





int dhtmlCompiler::checkCloseOutput(Buffer* x,miner *n)
{
   if(n->mine(*x,"~%close%~%output~%")){ 
	     delete x;
         codeBuff[ip].param=0;  
         codeBuff[ip++].Instruction=closeOutput;
         return 1;
        }
   return(0);
}



int dhtmlCompiler::checkTable(Buffer* x, miner *n)
{
	if(n->mine(*x,"~%TABLE%~%`*`=~%`*`.`*`")){
		delete x;
		if((x=n->getValueFinal(2))!=0)
			trim(x);
		Buffer *y=n->getValueFinal(1);
		if(y)
			trim(y);
		Buffer *tname=n->getValueFinal(0);
		if(tname) trim(tname);
		if(evaluateExp(&x,n)==0){
			codeBuff[ip].Instruction=moveParamToRegisterB;
			codeBuff[ip++].param=x;
		}else{
			codeBuff[ip++].Instruction=moveRegisterAtoB;
		}
		if(evaluateExp(&y,n)==0){
			codeBuff[ip].Instruction=moveParamToRegisterA;
			codeBuff[ip++].param=y;
        }
		codeBuff[ip].param=tname;
		codeBuff[ip++].Instruction=createTable;
		return 1;
	}
	return 0;
}



int dhtmlCompiler::checkQuery(Buffer* x, miner* n)
{
	if(x!=0)
		if(n->mine(*x,"~%select%~%*from%~%`*`%~%`*`")){
			delete x;
			htmlCode *code=&codeBuff[ip++];
			code->Instruction=moveParamToRegisterA;
			if((code->param=n->getValueFinal(1))!=0)
				trim(code->param);
			code=&codeBuff[ip++];
			code->Instruction=sqlQuery;
			code->param=n->getValueFinal(0);
			return 1;
		}else
		if(n->mine(*x,"~%Also%~%select%~%*from%~%`*`%~%`*`")){
			delete x;
			htmlCode *code=&codeBuff[ip++];
			code->Instruction=moveParamToRegisterA;
			if((code->param=n->getValueFinal(1))!=0)
				trim(code->param);
			code=&codeBuff[ip++];
			code->Instruction=alsoQuery;
			code->param=n->getValueFinal(0);
			return 1;
		}
	return 0;
}


int  dhtmlCompiler::compile(miner *m, Buffer *x)
{
	if(x==0)
		return 1;
	int ipl;
	if (checkSwitch(x,m))
		return 1;
    if (checkSwitchEnd(x,m))
		return 1;
	if (checkDefault(x,m))
		return 1;
	if (checkCase(x,m))
		return 1;
	if(checkString(x,m))
		return 1;
	if(checkFolder(x,m))
		return 1;
	if(checkSchedule(x,m))
		return 1;
	if(checkEventHandler(x,m))
		return 1;
	if(checkUser(x,m))
		return 1;
	if(checkFile(x,m))
		return 1;
	if(checkLabel(x,m))
		return 1;
	if(checkSleep(x,m))
		return 1;
	if(checkLock(x,m))
		return 1;
	if(checkRelease(x,m))
		return 1;
	if(checkGoto(x,m))
		return 1;
	if(checkObject(x,m)){
		return 1;
	}
	if(checkVar(x,m)){
		return 1;
	}
	if(checkQuery(x,m))
		return 1;
	if(checkIfTrue(x,m)){
		return 1;
	}
	if(checkAssignment(x,m)){
		return 1;
	}
	if(checkAddition(x,m)){
		return 1;
	}
	if(checkSubstraction(x,m)){
		return 1;
	}
	if(checkDiv(x,m)){
		return 1;
	}
	if(checkMul(x,m)){
		return 1;
	}
	if(checkMod(x,m)){
		return 1;
	}
	if(checkCmd(x,m))
		return 1;
	if(checkExec(x,m))
		return 1;
	if(checkFTP(x,m))
		return 1;
	if(checkHost(x,m))
		return 1;
	if(checkForm(x,m))
		return 1;
	if(checkMail(x,m))
		return 1;
	if(checkTime(x,m))
		return 1;
	if(checkInclude(x,m))
		return 1;
	if(checkLoopStart(x,m))
		return 1;
	if(checkLoopEnd(x,m))
		return 1;
	if(checkOutput(x,m))
		return 1;
	if(checkQueue(x,m))
		return 1;
	if(checkCloseOutput(x,m))
		return 1;
	if(checkTable(x,m))
		return 1;
	if(checkElse(x,m))
		return 1;
	if(checkEndIf(x,m))
		return 1;
    if(checkQuitLoops(x,m))
		return 1;
	if(checkOver(x,m))
		return 1;
	if(checkSuspend(x,m))
		return 1;
	if(checkDispatch(x,m))
		return 1;
	if(checkBreak(x,m))
		return 1;
	if(checkDelete(x,m))
		return 1;
	if(checkRegister(x,m))
		return 1;
	if(checkFlush(x,m))
		return 1;
	if(checkRebuild(x,m))
		return 1;
	if(checkSubstitute(x,m))
		return 1;
	if(checkMode(x,m))
		return 1;
	if(checkIfDomain(x,m))
		return 1;
	ipl=ip;
	Buffer *sizeBuff=0;
	if(m->mine(*x,"`*`<size~%=~%`*`>")){
		delete x;
		int osize;
		x=m->getValueFinal(1);
		if(x)
			trim(x);
		if((osize=atoi(*x))!=0)
			sizeBuff=x;
		else
			delete x;
		x=m->getValueFinal(0);
		if(x)
			trim(x);
	}
	if(evaluateExp(&x,m)){
		if(ip > ipl){
			codeBuff[ip].param=sizeBuff;
			codeBuff[ip++].Instruction=outputRegister;
		}
		return 1;
	}else{
		delete x;
		if(sizeBuff){
			codeBuff[ip++].Instruction=moveParamToRegisterA;
			codeBuff[ip].param=sizeBuff;
			codeBuff[ip++].Instruction=outputRegister;
			return 1;
		}
	}
	return 0;
}

//extern htmlObject *persistentObjects[100];
/*
genericObject* deleteObj(genericObject *x,genericObject *fobj)
{
	if(x==0 || fobj == 0)
		return 0;
	genericObject* t=0;
	for(;fobj!=0;fobj=fobj->next){
		if((fobj==x) && ((fobj->getType()!=TYPFILE) || (((htmlFile*)fobj)->islockf()==0)))
			break;
		t=fobj;
	}
	if(fobj && t){
		t->next=fobj->next;
		t=t->next;
		if((t==0)  || (t->equals(fobj->getName())==0))
			t=0;
		fobj->setPersistent(0);
		delete fobj;
	}
	return t;
}
*/

int addObject(genericObject *x,genericObject *fobj, int code)
{
	if(x!=0){
		if(fobj!=0){
			genericObject *prev=fobj;
			genericObject *first=0;
			char *n=x->getName();
			for(genericObject *o=fobj->next;o!=0;o=o->next) {
				if(o->equals(n)){
					if((code!=0) && (o->getInstance()==code)){
						if(o->getType()!=TYPLOOP){
							if((o->getType()!=TYPFILE) || (((htmlFile*)o)->islockf()==0)){
								prev->next=o->next;
								if(o->getType()!=TYPFORM || o->submit()==0){
									delete o;
								}
								break;
							}
						}
					}
					if(first==0){
						first=prev;
					}
				}
				prev=o;
			}
			if (first)
				prev=first;
			x->prev=prev;
			if(prev->next){
				x->next=prev->next;
				x->next->prev=x;
			}else
				x->next=0;
			prev->next=x;
			x->setInstance(code);
			symTab *vs=(symTab*)fobj->showValue(SYMINFO);
			if(vs!=0)
				vs->objects[getSymbol(x->getName(),vs->symbols,&vs->symtotal)]=x;
			return 1;
		}
		delete x;
	}
	return 0;
}

void changeObjName(genericObject* x,char *onam)
{
	genericObject *fobj=x;
	while(fobj->prev)
		fobj=fobj->prev;
	symTab *vs=(symTab*)fobj->showValue(SYMINFO);
	if(vs!=0){
		int n=getSymbol(onam,vs->symbols,&vs->symtotal);
		if(vs->objects[n]==x){
			vs->objects[n]=0;
			if(x->next && x->next->equals(onam)){
				vs->objects[n]=x->next;
			}
		}
		vs->objects[getSymbol(x->getName(),vs->symbols,&vs->symtotal)]=x;
	}
}

int deleteObj(char *x,genericObject *objs)
{
	if(x==0)
		return 0;
	genericObject* fobj=objs;
	genericObject* t=0;
	for(;fobj!=0;fobj=fobj->next){
		if(fobj->equals(x) && ((fobj->getType()!=TYPFILE) || (((htmlFile*)fobj)->islockf()==0)))
			break;
		t=fobj;
	}
	if(fobj && t){
		t->next=fobj->next;
		if(t->next)
			t->next->prev=t;
		symTab *vs=(symTab*)objs->showValue(SYMINFO);
		if(vs!=0){
			char *onam=fobj->getName();
			int n=getSymbol(onam,vs->symbols,&vs->symtotal);
			if(n && (vs->objects[n]==fobj)){
				vs->objects[n]=0;
				while(t->next){
					t=t->next;
					if(t->equals(onam)){
						vs->objects[n]=t;
						break;
					}
				}
			}
		}
		fobj->setPersistent(0);
		delete fobj;
		return 1;
	}
	return 0;
}


genericObject*  getObject(char* n,genericObject *fobj)
{
	for(genericObject* l=fobj;l!=0;l=l->next){
		if(l->equals(n)){
			if(l->getType()==TYPPROXY){
				l=((proxy*)l)->getOriginal();
			}
			return(l); 
		}
	}
	return 0;
}


int getbType(char* a,int *aprec);

/*
int hcmp(Buffer *x,Buffer* y)
{
	if(x==0 || y==0)
		return -1;
	char *a=*x;
	char *b=*y;
	int aprec;
	int atype=getbType(a,&aprec);
	if(atype<2){
		int bprec;
		int btype=getbType(b,&bprec);
		if(btype<2){
			if(atype || btype){
				double ai=atof(a);
				double bi=atof(b);
				return(ai==bi?0:(ai>bi)?1:-1);
			}else{
				int ai=atoi(a);
				int bi=atoi(b);
				return(ai==bi?0:(ai>bi)?1:-1);
			}
		}

	}
	int n=x->getSize()-1;
	int m=y->getSize()-1;
	if(n==m)
		return(memicmp(a,b,n));
	if(n>m){
      n=memicmp(a,b,m);
      if(n==0)
		return 1;
      else
		return n;
	}else{
		m=memicmp(a,b,n);
		if(m==0)
			return -1;
		else
			return m;
	}
}
*/

typedef struct {
	htmlBuffer *acc;
	char op;
	char type;
	char prec;
	char y;
	double x;
}ACC;


int Compare(double x,double y,int op)
{
	switch(op){
	case GTE:
		return (x>=y);
	case LTE:
		return(x<=y);
	case EQU:
	case NTE:
		return(x!=y);
	case GT:
		return (x>y);
	case LT:
		return(x<y);
	}
	return 0;
}

int Compare(char* a,char *b,int op)
{
	switch(op){
		/*
	case MATCH:
		{
			miner *m=new miner();
			int rc=m->mine(a,b);
			delete m;
			return rc==0;
		}
		*/
	case GTE:
		return(stricmp(a,b)>=0);
	case LTE:
		return(stricmp(a,b)<=0);
	case EQU:
	case NTE:
		return(stricmp(a,b)!=0);
	case GT:
		return(stricmp(a,b)>0);
	case LT:
		return(stricmp(a,b)<0);
	}
	return 0;
}


int compare(ACC *acc,htmlBuffer *t,double facc,int type,Buffer *cp,int prec,genericObject *objs)
{
	int rc=(acc->x!=0);
	htmlBuffer *o=t;
	if(acc->op>=OR){
		acc->prec=0;
		if((acc->type&3)>0){
			rc=0;
			if(acc->type==3){
				if(getObject(*acc->acc,objs))
					rc=1;
			}else{
				t=acc->acc;
				while(t){
					if(t->isValid() && t->getSize()>1){
						rc=1;
						break;
					}
					t=t->next;
				}
			}
		}
		if(((rc!=0) && acc->op==OR) || (rc==0 && acc->op==AND))
				return rc;
		if((type&3)>0){
			rc=0;
			if(type==3){
				if(getObject(*cp,objs))
					rc=1;
			}else{
				t=o;
				while(t){
					if(t && t->isValid() && t->getSize()>1){
						rc=1;
						break;
					}
					t=t->next;
				}
			}
		}else{
			rc=(facc!=0);
		}
		return rc;
	}
	double x=acc->x;
	rc=(acc->op<=EQU || acc->op==NTE);
	switch(acc->type&3){
	case 0:
		switch(type&3){
		case 0:
			rc=Compare(x,facc,acc->op);
			break;
		case 3:
			if(getbType(*cp,&prec)<2)
				rc=Compare(x, atof(*cp),acc->op);
			break;
		case 2:
			rc=Compare(x,facc,acc->op);
			if(rc==0)
				break;
			t=t->next;
		case 1:
			while(t){
				if(getbType(*t,&prec)<2)
					rc=Compare(x,atof(*t),acc->op);
				if(rc==0)
					break;
				t=t->next;
			}
			break;
		}
	break;
	case 2:
		switch(type&3){
		case 0:
			rc=Compare(x,facc,acc->op);
			if(rc==0)
				break;
			t=acc->acc->next;
			goto case10;
		case 3:
			if(getbType(*cp,&prec)<2)
				rc=Compare(x,atof(*cp),acc->op);
			if(rc==0)
				break;
			if(acc->acc->next!=0){
				t=acc->acc;
				acc->acc=t->next;
				delete t;
				goto case13;
			}
			break;
		case 2:
			rc=Compare(x,facc,acc->op);
			if(rc==0)
				break;
			t=t->next;
		case 1:
			while(t){
				if(getbType(*t,&prec)<2)
					rc=Compare(x,atof(*t),acc->op);
				if(rc==0)
					break;
				t=t->next;
			}
			if(rc!=0){
				if(acc->acc->next!=0){
					t=acc->acc;
					acc->acc=t->next;
					delete t;
					goto case12;
				}

			}
			break;
		}
		break;
	case 3:
	case 1:
		switch(type&3){
		case 0:
			t=acc->acc;
case10:
			while(t){
				int aprec;
				if(getbType(*t,&aprec)<2)
					rc=Compare(atof(*t),facc,acc->op);
				if(rc==0)
					break;
				t=t->next;
			}
			break;
		case 3:
case13:
			{
				t=acc->acc;
				int btype=(getbType(*cp,&prec)<2);
				if(btype){
					facc=atof(*cp);
				}else{
					if(stricmp(*t,"domain")==0){
						htmlObject *ui=(htmlObject*)getObject(sUSERINFO,objs);
						rc=((ui && ui->getValue(sDOMAIN,*cp))==0);
						break;
					}
				}
				while(t){
					int atype=(getbType(*t,&prec)<2);
					if(btype){
						if(atype)
							rc=Compare(atof(*t),facc,acc->op);
					}else{
						if(atype==0){
							rc=Compare(*t,*cp,acc->op);
						}
					}
					if(rc==0)
						break;
					t=t->next;
				}
			}
			break;
		case 1:
		case 2:
case12:
			htmlBuffer *p=acc->acc;
			if(stricmp(*p,"domain")==0){
				htmlObject *ui=(htmlObject*)getObject(sUSERINFO,objs);
				rc=((ui && ui->getValue(sDOMAIN,*o))==0);
				break;
			}
			while(p){
				t=o;
				int atype=(getbType(*p,&prec)<2);
				double px;
				if(atype<2){
					px=atof(*p);
				}
				while(t){
					int btype=(getbType(*t,&prec)<2);
					if(atype){
						if(btype)
							rc=Compare(px,atof(*t),acc->op);
					}else{
						if(btype==0)
							rc=Compare(*p,*t,acc->op);
					}
					if(rc==0)
						break;
					t=t->next;
				}
				if(rc==0)
					break;
				p=p->next;
			}
		}
		break;
	}
	if(acc->op<=EQU){
		rc^=1;
	}
	return rc;
}


int quitCar=0;
int quitLoop=0;

void addObject(genericObject *o,genericObject** p,genericObject* first,int code)
{
	o->setInstance(code);
	if((*p==0) || (*p==first)){
		o->next=first->next;
		o->prev=first;
		first->next=o;
		if(o->next)
			o->next->prev=o;
		*p=o;
	}else{
		o->next=*p;
		o->prev=(*p)->prev;
		(*p)->prev=o;
		o->prev->next=o;
		*p=o;
		while(o->next->equals(o->getName())){
			o=o->next;
			if((o->getInstance()==code) && (o->getType()!=TYPLOOP)){
				if(o->next)
					o->next->prev=o->prev;
				o->prev->next=o->next;
				if(o->getType()!=TYPFORM || o->submit()==0)
					delete o;
				break;
			}
			if(o->next==0)
				break;
		}
	}
}


genericObject* deleteObjfast(genericObject* p)
{
	genericObject *o=p->next;
	p->prev->next=o;
	if(o!=0){
		o->prev=p->prev;
		if(o->equals(p->getName())==0)
			o=0;
	}
	p->setPersistent(0);
	if(p->getType()!=TYPFORM || p->submit()==0)
		delete p;
	return o;
}


int caravanLocked=0;

void compileEncrypted(File *fi,dhtmlCompiler* x)
{
	encryptFile(fi,0);
	fi->seekTo(0);
	LZW *l=new LZW();
	File* f;
	while((f=l->expand(fi))!=0){
		x->compile(f);
		f->deleteFile();
		delete f;
	}
	delete l;
}

char *sTerminate="_terminate";

void dhtml::output(genericObject *objs,Runnable* thread,File *of)
{
	int rc=0;
	int lc=0;
	int editLocked=0;
	editLock->lock();
	refresh();
	lock++;
	int instance=incActiveCount(getName());
	editLock->release();
	int mode=0;
	wSpace *xSpace=0;
	register htmlCode *code;
	htmlBuffer *registerA=0;
	htmlBuffer *registerB=0;
	htmlBuffer *registerC=0;
	htmlBuffer *tmp1;
	htmlBuffer *tmp2;
	int event=0;
	char* chrPtr;
	char opx;
	ULONG ivar=0;
	int over=0;
	int count=(int)&lock;
	int modeAssign=0;
	int modeIgnoreCase=0;
	int mlocked=0;
	char btmp[sizeof(ACC)*128];
    ACC *acc=(ACC*)(btmp);
	char* atmp=btmp+(sizeof(ACC)*120);
	memset(acc,0,sizeof(ACC));
	acc->op=-1;
	int ttype=0;
	double facc;
	int prec;
	genericObject *o;
	genericObject *objFile=0;
	File *outFile = of;
	int i;
	int objSize=sizeof(genericObject*)*symtotal;
	char *objbuff=(char*)alloca(objSize);
	memset(objbuff,0,objSize);
	genericObject **objects=(genericObject**)(objbuff);
	for(o=objs;o!=0;o=o->next){
		if(((i=getSymbol(o->getName(),symbols,&symtotal))!=0) && (objects[i]==0))
			objects[i]=o;
	}
	if((o=objects[eventAt])!=0){
		if(o->getType()==TYPQUEUE)
			event=((queue*)o)->getHandle();
	}
	o=0;
	symTab vs;
	vs.symbols=symbols;
	vs.objects=objects;
	vs.symtotal=symtotal;
	objs->putValue(SYMINFO,new htmlBuffer(new Buffer((char*)&vs,sizeof(vs))));
	for(i=0;(over==0) && (i<ip);++i){
		code=codeBuff+i;
		switch(code->Instruction){
		case putOp:
			acc->op=(int)code->param;
			break;
		case pushAcc:
			acc++;
			memset(acc,0,sizeof(ACC));
			acc->op=-1;
			break;
		case popAcc:
			ttype=acc->type;
			if((ttype&1)==0){
				facc=acc->x;
				prec=acc->prec;
			}else
				ttype=1;
			tmp1=acc->acc;
			acc--;
			goto calc;
			break;
		case putQuot:
			ttype=3;
			tmp1=0;
			goto calc;
			break;
		case putRegisterA:
			ttype=1;
			tmp1=registerA;
			if(registerA && registerA->isValid()){
				if(getbType(*tmp1,&prec)<2){
					facc=atof(*tmp1);
					if ((strlen(*tmp1)>1) && (*((char*)*tmp1)=='0'))
						ttype=4;
					else
						ttype=2;
				}
				registerA=0;
			}else{
				if(acc->op!=DOT){
					deleteRegisterA;
					tmp1=0;
				}else{
					registerA=0;
				}
				if(tmp1==0)
					tmp1=new htmlBuffer("");
				tmp1->setValid(0);
			}
			goto calc;
			break;
		case putToken:
			tmp1=0;
			if(getbType(*code->param,&prec)<2){
				facc=atof(*code->param);
				if((strlen(*code->param)>1) && (*((char*)*code->param)=='0'))
					ttype=4;
				else
					ttype=0;

			}else{
				ttype=3;
			}
calc:
			opx=0;
			switch(acc->op){
			case -1:
				acc->type=ttype;
				acc->acc=tmp1;
				if((ttype&1)==0){
					acc->prec=prec;
					acc->x=facc;
				}else{
					if(ttype==3)
						acc->acc=new htmlBuffer(new Buffer(*code->param,code->param->getSize()));
				}
				tmp1=0;
				goto skipDel;
				break;
			case ADD:
				if(((acc->type&1)==0) && ((ttype&1)==0)){
					acc->x+=facc;
				}else{
addIT:
					int l;
					int n;
					Buffer *x;
					char *p;
					char *s;
					if(ttype&1){
						if(ttype==3){
							p=*code->param;
							n=code->param->getSize();
						}else{
							n=tmp1->getSize();
							p=*tmp1;
						}
					}else{
						if(((acc->type&1)==0) || (tmp1==0)){
							if(prec)
								snprintf(atmp,32,"%f",facc);
							else{
								if(ttype&4&&(facc>0))
									snprintf(atmp,32,"0%d",(int)facc);
								else
									snprintf(atmp,32,"%d",(int)facc);
							}
							if(tmp1)
								deleteHtmlBuffer(tmp1);
							tmp1=new htmlBuffer(atmp);
						}
						p=*tmp1;
						n=tmp1->getSize();
					}
					if((acc->type&1)==0){
						x=new Buffer(n+65);
						s=*x;
						if(acc->prec){
							snprintf(atmp,12,"%%.%df",acc->prec);
							l=snprintf(s,64,atmp,acc->x);
						}else{
							if(acc->type&4 && (acc->x>0))
								l=snprintf(s,64,"0%d",(int)acc->x);
							else
								l=snprintf(s,64,"%d",(int)acc->x);
						}
					}else{
						l=acc->acc->getSize()-1;
						x=new Buffer(l+n+1);
						s=*x;
						memcpy(s,(char*)*(acc->acc),l);
					}
					if(opx){
						s[l++]=opx;
					}
					memcpy(s+l,p,n);
					x->setSize(l+n);
					deleteHtmlBuffer(acc->acc);
					acc->acc=new htmlBuffer(x);
					acc->type=1;
				}
				break;
			case SUB:
				if(((acc->type&1)==0) && ((ttype&1)==0)){
					acc->x-=facc;
				}else{
					opx='-';
					goto addIT;
				}
				break;
			case DOT:
				opx='.';
                goto addIT;
			case MUL:
				if(((acc->type&1)==0) && ((ttype&1)==0)){
					acc->x*=facc;
				}else{
					opx='*';
					goto addIT;
				}
				break;
			case DIV:
				if(((acc->type&1)==0) && ((ttype&1)==0)){
					if(facc!=0){
						acc->x/=facc;
					}else{
						deleteHtmlBuffer(acc->acc);
						acc->acc=new htmlBuffer("divide by zero");
						acc->type=1;
					}
				}else{
					opx='/';
					goto addIT;
				}
				break;
			case MOD:
				if(((acc->type&1)==0) && ((ttype&1)==0)){
					if(prec==0 && acc->prec==0){
						int x=(int)facc;
						if(x>0){
							int z=(int)acc->x;
							z%=x;
							acc->x=z;
						}else
							acc->x=0;
						acc->prec=0;
					}else{
						deleteHtmlBuffer(acc->acc);
						acc->acc=new htmlBuffer("invalid operation %");
						acc->type=1;
					}
				}else{
					opx='%';
					goto addIT;
				}
				break;
			case MATCH:
				if (ttype&1){
					miner *m=new miner();
					acc->x=0;
					if(ttype==3){
						for(htmlBuffer *h=acc->acc;h!=0;h=h->next){
							if(m->mine(*h,*code->param)){
								acc->x=1;
								break;
							}
						}
					}else{
						htmlBuffer* pattern=tmp1;
						if(pattern && acc->acc){
							for(htmlBuffer *h=acc->acc;(h!=0) && (acc->x==0);h=h->next){
								for(;pattern!=0;pattern=pattern->next){
									if(m->mine(*h,*pattern)){
										acc->x=1;
										break;
									}
								}
							}
						}
					}
					delete m;
					acc->prec=0;
					acc->type=0;
					ttype=0;
				}
				break;
			default:
				acc->x=compare(acc,tmp1,facc,ttype,code->param,prec,objs);
				acc->prec=0;
				acc->type=0;
				ttype=0;
				break;
			}
			if((acc->type&1)==0){
				acc->type&=4;
				acc->type|=(ttype&4);
				deleteHtmlBuffer(acc->acc);
				acc->acc=0;
			}
			acc->op=-2;
			deleteHtmlBuffer(tmp1);
			tmp1=0;
skipDel:
			break;
		case popAccToRegisterA:
		case moveAccToRegisterA:
			if ((acc->type&1)==0){
				if(acc->prec>0){
					chrPtr=atmp+48;
					snprintf(chrPtr,8,"%%.%df",acc->prec);
					snprintf(atmp,48,chrPtr,acc->x);
				}else{
						if(acc->type&4 && (acc->x>0))
							snprintf(atmp,20,"0%d",(int)acc->x);
						else
							snprintf(atmp,20,"%d",(int)acc->x);
				}
				registerA=new htmlBuffer(atmp);
				deleteHtmlBuffer(acc->acc);
			}else{
				registerA=acc->acc;
			}
			if(code->Instruction==popAccToRegisterA)
				acc--;
			else{
				acc->acc=0;
				acc->op=-1;
			}
			break;
		case adminCheck:
		case domainCheck:
			over=1;
			if(registerA){
				if((o=objects[code->object])!=0){
					if(o->getType()==TYPPROXY)
						o=((proxy*)o)->getOriginal();
					over=!((htmlObject*)o)->getValue(sDOMAIN,*registerA);
				}
				if(over)
					over=!checkDomain(objs,*registerA,code->Instruction==adminCheck);
				deleteRegisterA;
			}
			if(over){
				login(outFile,objs,getName());
				rc=1;
			}
			break;
		case Lock:
				if(mlocked==0){
					if(mlock==0)
						mlock=new mutex();
					mlock->lock();
					mlocked=1;
				}
				break;
		case Release:
			if(mlocked){
				mlock->release();
				mlocked=0;
			}
			break;
		case suspend:
			waitEvent(event);
			break;
		case quit:
			over=1;
			break;
		case outputParam:
			if(code->param){
				Buffer *outb=code->param;
				int del=0;
				if(mode>=2){
					mode-=2;
					outb=urlEncode(*code->param,code->param->getSize()-1);
					del=1;
				}else{
					if(mode && xSpace && (xSpace->getSize()>0)){
						outb=convertText(*code->param,code->param->getSize()-1,xSpace);
						del=1;
					}
				}
				if(outb)
					outFile->write(*outb,outb->getSize()-1);
				if(del)
					delete outb;
			}
			break;
		case outputRegister:
			{
				int ivar;
				if(code->param)
					ivar=atoi(*code->param);
				else
					ivar=-1;
				char delim[2]={0,0};
				while(registerA!=0){
                    if(*delim>2){
						if(xSpace){
							Buffer* tmp=convertText(delim,1,xSpace);
							outFile->write(*tmp,tmp->getSize()-1);
							delete tmp;
						}else
							outFile->write(delim,1);
					}
					tmp1=registerA->next;
					if(registerA->isValid()!=0){
						if(*delim<=2)
							*delim=registerA->isValid();
						ULONG wr;
						if(mode){
							if(ivar!=0){
								Buffer *tmp;
								if(mode>=2)
									tmp=urlEncode(*registerA,registerA->getSize()-1);
								else{
									if(xSpace && (xSpace->getSize()>0)){
										File* fd=registerA->getFile();
										if((fd==0) || (fd->size()<20480)){
											tmp=convertText(*registerA,registerA->getSize()-1,xSpace);
										}else{
											char outbuffer[10240];
											fd->seekTo(0);
											int nread;
											do{
												nread=fd->read(outbuffer,10240);
												if(nread>0){
													tmp=convertText(outbuffer,nread,xSpace);
													outFile->write(*tmp,tmp->getSize()-1);
													delete tmp;
												}
											}while(nread==10240);
											tmp=0;
										}
									}
									else
										goto binaryMode;
								}
								if(tmp!=0){
									int os=tmp->getSize()-1;
									if(ivar>0){
										if(os>ivar)
											os=ivar;
									}
									wr=outFile->write(*tmp,os);
									ivar-=wr;
									delete tmp;
									if(tmp1==0 && ivar>0){
										Buffer *tmp=new Buffer(os=ivar);
										memset(*tmp,' ',os);
										outFile->write(*tmp,os);
										delete tmp;
									}
								}
							}
						}else{
binaryMode:
							if((registerA->getFile()==0) || (registerA->getSize() < 0x10000)){
								char *s=*registerA;
								int sz=registerA->getSize()-1;
								if (ivar !=-1 && ivar < sz)
									sz=ivar;
								wr=outFile->write(s,sz);
							}else{
								File *fd=registerA->getFile();
								if(fd){
									fd->seekTo(0);
									int nread;
									Buffer *b=new Buffer(BFSIZE);
									char *s=*b;
									do{
										nread=fd->read(s,BFSIZE);
										outFile->write(s,nread);
									}while(nread==BFSIZE);
									delete b;
									fd->close();
								}
							}
						}
					}
					delete registerA;
					registerA=tmp1;        
				}
				if(mode>=2)
					mode-=2;
			}
			break;
		case moveRegisterAtoB:
			registerB=registerA;
			registerA=0;
			break;
		case moveRegisterAtoC:
			registerC=registerA;
			registerA=0;
			break;
		case moveParamToRegisterA:
			if(code->param)
				registerA=new htmlBuffer(new Buffer(*code->param,code->param->getSize()));
			else
				registerA=0;
			break;
		case moveParamToRegisterB:
			if(code->param)
				registerB=new htmlBuffer(new Buffer(*code->param,code->param->getSize()));
			else
				registerB=0;
			break;
		case moveParamToRegisterC:
			if(code->param)
				registerC=new htmlBuffer(new Buffer(*code->param,code->param->getSize()));
			else
				registerC=0;
			break;
		case getValueRegister:
			{
				tmp2=tmp1=registerA;
				registerA=0;
				if(code->param && tmp1){
					if(isIndex(*tmp1)==0){
						if((o = objects[code->object])!=0){
							if(lc=(o->getType()==TYPPROXY)){
								o=((proxy*)o)->getOriginal();
								o->lock();
							}
							registerA=o->getValue(tmp1);
							if(lc)
								o->release();
						}
					}
					if(registerA==0){
						int n;
						htmlBuffer *last=0;
						while(tmp1){
							Buffer *z=new Buffer(n=tmp1->getSize()+code->param->getSize()+1);
							snprintf(*z,n,"%s(%s)",(char*)*code->param,(char*)*tmp1);
							if(registerA==0){
								last=registerA=new htmlBuffer(z);
							}else{
								last->next=new htmlBuffer(z);
								last=last->next;
							}
							tmp1=tmp1->next;
						}
						registerA->setInvalid();
					}else{
						char c=o->getDelim();
						if(c!=0){
							registerA->setValid(c);
						}
					}
				}
				deleteHtmlBuffer(tmp2);
			}
			break;
		case putValueRegisterB:
			if(registerB && ((registerA==0) || (registerA->isValid()))){
				lc=0;
				if((o = objects[code->object])!=0){
					if(lc=(o->getType()==TYPPROXY)){
						o=((proxy*)o)->getOriginal();
					}
presp:
					if(lc)
						o->lock();
					if(modeAssign && mode && xSpace && (xSpace->getSize()>0)){
							o->putValue((Buffer*)*registerB,filter(registerA,&mode,xSpace));
					}else
						o->putValue((Buffer*)*registerB,registerA);
					if(lc)
						o->release();
					registerA=0;
				}else{
					if(code->param && (stricmp(*code->param,sRESPONSE)==0)){
						o = new htmlObject(new Buffer(sRESPONSE,RESPONSEl));
						addObject(o,&objects[code->object],objs,(int)code);
						goto presp;
					}
				}
			}
			deleteRegisterA;
			deleteRegisterB;
			break;
		case addValueRegisterB:
			if(registerA && registerA->isValid() && registerB){
				if((o = objects[code->object])!=0){
					if(lc=(o->getType()==TYPPROXY)){
						o=((proxy*)o)->getOriginal();
						o->lock();
					}
					if(modeAssign && mode && xSpace && (xSpace->getSize()>0))
						o->addValue((Buffer*)*registerB,filter(registerA,&mode,xSpace));
					else
						o->addValue((Buffer*)*registerB,registerA);
					if(lc)
						o->release();
					registerA=0;
				}
			}
			deleteRegisterA;
			deleteRegisterB;
			break;
		case subValueRegisterB:
			if(registerA && registerA->isValid() && registerB){
				if((o = objects[code->object])!=0){
					if(lc=(o->getType()==TYPPROXY)){
						o=((proxy*)o)->getOriginal();
						o->lock();
					}
					o->subValue((Buffer*)*registerB,registerA);
					if(lc)
						o->release();
					registerA=0;
				}
			}
			deleteRegisterA;
			deleteRegisterB;
			break;
		case mulValueRegisterB:
			if(registerA && registerA->isValid() && registerB){
				if((o = objects[code->object])!=0){
					if(lc=(o->getType()==TYPPROXY)){
						o=((proxy*)o)->getOriginal();
						o->lock();
					}
					o->mulValue((Buffer*)*registerB,registerA);
					if(lc)
						o->release();
					registerA=0;				}
			}
			deleteRegisterA;
			deleteRegisterB;
			break;
		case divValueRegisterB:
			if(registerA && registerA->isValid() && registerB){
				if((o = objects[code->object])!=0){
					if(lc=(o->getType()==TYPPROXY)){
						o=((proxy*)o)->getOriginal();
						o->lock();
					}
					o->divValue(*registerB,registerA);
					if(lc)
						o->release();
					registerA=0;
				}
			}
			deleteRegisterB;
			deleteRegisterA;
			break;
		case modValueRegisterB:
			if(registerA && registerA->isValid() && registerB){
				if((o = objects[code->object])!=0){
					if(lc=(o->getType()==TYPPROXY)){
						o=((proxy*)o)->getOriginal();
						o->lock();
					}
					o->modValue(*registerB,registerA);
					if(lc)
						o->release();
					registerA=0;
				}
			}
			deleteRegisterA;
			deleteRegisterB;
			break;
		case createFile:
			if(registerA && registerA->isValid()){
				o=new htmlFile(new Buffer(*code->param,code->param->getSize()),registerA,event,objs,(int)code);
				addObject(o,&objects[code->object],objs,(int)code);
				registerA=0;
			}else
				deleteRegisterA;
			break;
		case createObject:
				o = new xmlObject(new Buffer(*code->param,code->param->getSize()));
				addObject(o,&objects[code->object],objs,(int)code);
			break;
		case createObjectFromFile:
			if(registerA){
				o = new xmlObject(new Buffer(*code->param,code->param->getSize()),registerA,objs,(int)code);
				addObject(o,&objects[code->object],objs,(int)code);
				deleteRegisterA;
			}
			break;
		case createVar:
			o=new htmlObject(new Buffer(*code->param,code->param->getSize()));
			addObject(o,&objects[code->object],objs,(int)code);
			break;
		case createParser:
			if(code->param){
				if((o=objects[code->object])!=0){
					if(o->getInstance()==(int)code){
						objects[code->object]=deleteObjfast(o);
						o=0;
					}else{
						if(o->getType()==TYPPROXY){
							o=((proxy*)o)->getOriginal();
						}
						if(o->getType()!=TYPVAR){
							o=0;
						}
					}
				}
				if(registerA && registerB && registerC){
					miner *m=new miner();
					if(m->mine(*registerA,*registerB,registerA->getSize()-1)){
						if(o==0 || o->getType()==TYPVAR){
							int delt=1;
							if(o==0){
								o=new htmlObject(new Buffer(*code->param,code->param->getSize()));
								addObject(o,&objects[code->object],objs,(int)code);
								delt=0;
							}
							Words *w=new Words((char*)*registerC);
							char* word;
							int len;
							int wn=0;
							while((len=w->getWord(&word))!=0){
								w->next();
								word[len]=0;
								if(delt)
									o->putValue(word,NULLVALUE);
								Buffer *bf=m->getValueFinal(wn++);
								if(bf){
									o->putValue(word,new htmlBuffer(bf));
								}
							}
							delete w;
						}
					}else{
						if(o && o->getType()==TYPVAR){
							objects[code->object]=deleteObjfast(objects[code->object]);
						}
					}
					delete m;
				}else{
					if(o && o->getType()==TYPVAR){
						objects[code->object]=deleteObjfast(objects[code->object]);
					}
				}
			}
			deleteRegisterA;
			deleteRegisterB;
			deleteRegisterC;
			break;
		case createMail:
			{
				genericObject *u=getObject(sUSERINFO,objs);
				char userid[256];
				char *ipAddr=0;
				userid[0]=0;
				if(u){
					ipAddr=u->showValue("userid");
					if(ipAddr!=0)
						strcpy(userid,ipAddr);
					ipAddr=objs->showValue("address");
				}else{
					if(xauthenticated(objs)){
						strcpy(userid,getName());
						for(int i=0;userid[i]!=0;++i)
							if(userid[i]=='.'){
								userid[i]=0;
								break;
							}
					}
				}
				if(Domain && (userid[0]!=0)){
					Time *t=new Time();
					char mailtxt[256];
					if(ipAddr && *ipAddr)
						snprintf(mailtxt,256,"from %s by %s.%s at %s",ipAddr,location,Domain,t->rfcFormat());
					else
						snprintf(mailtxt,256,"from auto-generation by %s.%s at %s",location,Domain,t->rfcFormat());
					delete t;
					o=new htmlMail(new Buffer(*code->param,code->param->getSize()));
					o->putValue("Received",mailtxt);
					o->setReadOnly();
					int i=0;
					for(;userid[i]!=0;++i){
						if(userid[i]=='@')
							break;
					}
					if(userid[i]==0)
						snprintf(userid+i,128,"@%s",Domain);
					o->putValue("from",userid);
					addObject(o,&objects[code->object],objs,(int)code);
				}else{
					outFile->write("Mail error : userid required\r\n");
					rc=1;
					over=3;
				}
			}
			break; 
		case createForm:
			o=new htmlForm(new Buffer(*code->param,code->param->getSize()),event,objs);
			addObject(o,&objects[code->object],objs,(int)code);
			break;
		case createUser:
			{
				int cu=0;
				genericObject *u=getObject(sUSERINFO,objs);
				char *uid;
				if((u!=0) && ((uid=u->showValue("uid"))!=0))
					cu=atoi(uid);
				o=new httpUser(new Buffer(*code->param,code->param->getSize()),checkDomain(objs,"admin"),cu);
				addObject(o,&objects[code->object],objs,(int)code);
			}
			break;
		case eventHandler:
			if(registerA){
				if(registerEventHandler(getName(),*registerA,registerB)!=0){
					for(int j=0;j<i;++j){
						if(codeBuff[j].Instruction < JUMPCODES){
							delete codeBuff[j].param;
							codeBuff[j].param=0;
						}
						codeBuff[j].Instruction=NOP;
					}	
					code->Instruction=NOP;
					codeBuff[0].param=(Buffer*)i;
					codeBuff[0].Instruction=jmp;
					setEventHandler();
				}else{
					objs->putValue(stayAlive,"yes");
				}
				registerB=0;
			}
			deleteRegisterB;
			deleteRegisterA;
			over=1;
			rc=1;
			break;
		case checkIfEventHandler:
			if(objs){
				registerA=objs->getValue("A\r\nA");
				registerB=objs->getValue("B\r\nB");
			}
			if(registerA == 0){
				over=1;
				break;
			}
			event=objs->getInstance();
			o=new queue(new Buffer(*code->param,code->param->getSize()),registerA,registerB,event);
			registerA=0;
			registerB=0;
			addObject(o,&objects[code->object],objs,(int)code);
			break;
		case createQueue:
			if(code->param && registerA){
				o=new queue(new Buffer(*code->param,code->param->getSize()),registerA,registerB,0);
				registerA=0;
				registerB=0;
				addObject(o,&objects[code->object],objs,(int)code);
				break;
			}
			deleteRegisterA;
			deleteRegisterB;
			break;
		case createTime:
			if(code->param){
				o=new httpTime(new Buffer(*code->param,code->param->getSize()));
				char *offsetTime=objs->showValue("offsetTime");
				if(offsetTime)
					((httpTime*)o)->offsetTime(atoi(offsetTime));
				addObject(o,&objects[code->object],objs,(int)code);
			}
			break;
		case createFolder:
			if(code->param && registerA){
				o=new htmlFolder(new Buffer(*code->param,code->param->getSize()),registerA);
				registerA=0;
				addObject(o,&objects[code->object],objs,(int)code);
			}else
				deleteRegisterA;
			break;
		case createFTP:
			if(code->param && registerA){
				o=new ftpObject(new Buffer(*code->param,code->param->getSize()),*registerA,event);
				addObject(o,&objects[code->object],objs,(int)code);
			}
			deleteRegisterA;
			break;
		case createHost:
			if(code->param && registerA){
				o=new ipHost(new Buffer(*code->param,code->param->getSize()),*registerA);
				addObject(o,&objects[code->object],objs,(int)code);
			}
			deleteRegisterA;
			break;
		case createTable:
			if(code->param && registerA && registerB){
				if(stricmp(*registerA,caravan)==0 && stricmp(*registerB,userTable)==0)
					goto skipTable;
				char *s=0;
				if((o=objects[cookieAt])!=0){
					s=o->showValue("seed");
				}
				o=new htmlTable(new Buffer(*code->param,code->param->getSize()),*registerA,*registerB,s,thread);
				addObject(o,&objects[code->object],objs,(int)code);
			}  
skipTable:
			deleteRegisterA;
			deleteRegisterB;
			break;
		case alsoQuery:
		case sqlQuery:
			if(registerA){
				genericObject *x = objects[code->object];
				if(x!=0){
					if(x->getType()==TYPPROXY){
						x=((proxy*)x)->getOriginal();
					}
					if(x->getType() == TYPTABLE){
						if((o=getObject("sql",objs))==0)
							o=getObject(sFORM,objs);
						((htmlTable*)x)->executeQuery(*registerA,o,code->Instruction==alsoQuery);
					}
				}
			}
			deleteRegisterA;
			break;
		case substituteString:
			if(registerA && registerB){
				mode=1;
				if(xSpace==0)
					xSpace=new wSpace();
				if(modeIgnoreCase){
					char *s=*registerA;
					int i,j;
					for(i=0;i<registerA->getSize()-1;++i){
						if(s[i]>='A' && s[i]<='Z'){
							s[i]+=32;
						}
					}
					s=*registerB;
					for(i=0;i<registerB->getSize()-1;++i){
						if(s[i]>='A' && s[i]<='Z'){
							s[i]+=32;
					}
					}
					xSpace->setPattern(new Buffer(*registerA,registerA->getSize()),*registerB);
					s=*registerA;
					if(*s>='a' && *s<='z')
						*s-=32;
					s=*registerB;
					if(*s>='a' && *s<='z')
						*s-=32;
					xSpace->setPattern(new Buffer(*registerA,registerA->getSize()),*registerB);
					s=*registerA;
					for(i=0,j=1;i<registerA->getSize()-1;++i){
						if((j==1) && (s[i]>='a' && s[i]<='z')){
							s[i]-=32;
							j=0;
						}
						j=((s[i]<'A' || s[i]>'Z') && (s[i]<'a' || s[i]>'z'));
					}
					s=*registerB;
					for(i=0,j=1;i<registerB->getSize()-1;++i){
						if((j==1) && (s[i]>='a' && s[i]<='z')){
							s[i]-=32;
							j=0;
						}
						j=((s[i]<'A' || s[i]>'Z') && (s[i]<'a' || s[i]>'z'));
					}
					xSpace->setPattern(new Buffer(*registerA,registerA->getSize()),*registerB);
					s=*registerA;
					for(i=0;i<registerA->getSize()-1;++i){
						if(s[i]>='a' && s[i]<='z')
							s[i]-=32;
					}
					s=*registerB;
					for(i=0;i<registerB->getSize()-1;++i){
						if(s[i]>='a' && s[i]<='z')
							s[i]-=32;
					}
				}
				xSpace->setPattern(new Buffer(*registerA,registerA->getSize()),*registerB);
			}
			deleteRegisterA;
			deleteRegisterB;
			break;
		case setModeReg:
			if(registerA && registerA->isValid()){
				chrPtr=*registerA;
				goto setMode;
			}
			deleteRegisterA;
			break;
		case setMode:
			registerA=0;
			chrPtr=*code->param;
setMode:
			if(stricmp(chrPtr,"ignorecase")==0){
				modeIgnoreCase^=1;
			}else
			if(stricmp(chrPtr,"assign")==0){
				modeAssign=1;
			}else
			if(stricmp(chrPtr,"output")==0){
				modeAssign=0;
			}else
			if(stricmp(chrPtr,"url")==0){
				if(mode<2)
					mode+=2;
			}else{
				if(stricmp(chrPtr,"off")==0){
					mode=0;
				}else
				if(stricmp(chrPtr,"on")==0){
					mode=1;
				}else{
					if(xSpace==0 || xSpace->getName()==0 || stricmp(xSpace->getName(),chrPtr)){
						mode=1;
						saveMode(xSpace);
						if((xSpace=getMode(chrPtr))==0)
							xSpace=new wSpace(chrPtr);
					}
				}
			} 
			deleteRegisterA;
			break;
		case includeFile:
			if(code->param){
				registerA=new htmlBuffer(*code->param);
			}
		case includeFileRegister:
			if(registerA && registerA->isValid()){
				{
					URLhandler *u = getURLhandler(*registerA);
					if(u!=0){
						deleteRegisterA;
						objs->putValue(SYMINFO,NULLVALUE);
						u->output(objs,thread,outFile);
						if(((i+1)<ip) && (codeBuff[i+1].Instruction!=includeFile)){
							memset(objbuff,0,objSize);
							for(o=objs;o!=0;o=o->next){
								int n=getSymbol(o->getName(),symbols,&symtotal);
								if(n!=0){
									if(objects[n]==0)
										objects[n]=o;
								}
							}
							objs->putValue(SYMINFO,new htmlBuffer(new Buffer((char*)&vs,sizeof(vs))));
						}
						if(objs->showValue(sTerminate)){
								over=1;
						}
						break;
					}
				}
				int delf=0;
				File *fp=registerA->getFile();
				if(fp==0){
					fp=new File(*registerA);
					if(fp->exists()==0){
						delete fp;
						fp=new File((*serverConfig)["documents"],*registerA);
					}
					delf=1;
				}
				char line[1024];
				int fr;
				if(mode==0 || xSpace==0 || xSpace->getSize()==0){
					do{
						if((fr=fp->read(line,1024))>0)
							outFile->write(line,fr);
					}while(fr==1024);
				}else{
					do{
						fr=fp->read(line,1024);
						Buffer *tmp=convertText(line,fr,xSpace);
						if (tmp!=0){
							outFile->write(*tmp,tmp->getSize()-1);
							delete tmp;
						}
					}while(fr==1024);
				}
				if(delf)
					delete fp;
			}
			deleteRegisterA;
			break;
		case loopStart:
			if (code->param){
				loop* loopx=new loop(new Buffer(*code->param,strlen(*code->param)+1),i+1);
				int k=0;
				if(registerA && registerA->isValid() && ((k=atoi(*registerA))>0)){
					loopx->setMaxCount(k);
					i++;
				}
				addObject(loopx,&objects[code->object],objs,(int)code);
			}
			deleteRegisterA;
			break;
		case quitLoops:
			quitLoop=1;
			SleepMilSec(20000);
			quitLoop=0;
			break;
		case repeatLoop:
			{
				loop *loopx=(loop*)objects[code->object];
NextI:
				int nextI=i;
				if(loopx && (loopx->getType()==TYPLOOP)){
					int k=0;
					if(loopx->continueLoop() && !quitCar && !quitLoop){
						i=loopx->getPos();
						if(registerA && registerA->isValid())
							k=atoi(*registerA);
						if((k!=0) && (loopx->getCount()>=k)){
							i=nextI;
						}else
							loopx->incCount();						
					}else{
						if(quitLoop){
							char  s[256];
							snprintf(s,256,"%s ending Loop : %s @ %d\r\n",getName(),loopx->getName(),loopx->getCount());
							caravanlog(s);
						}
					}
					if(i==nextI){
						i++;
						loopx->stopRunning();
					}
				}else{
					if(loopx){
						objects[code->object]=deleteObjfast(loopx);
						loopx=(loop*)objects[code->object];
						goto NextI;
					}
				}
			}
			deleteRegisterA;
			break;
		case rmLoop:
			{
				code--;
				loop *loopx=(loop*)objects[code->object];
				if((loopx!=0) && (loopx->getType()==TYPLOOP))
					loopx->stopRunning();
			}
			break;
		case appendToFileObj:
			ivar=1;
			goto fileObjInit;
		case writeToFileObj:
			ivar=0;
fileObjInit:
			{
				if (outFile!=of){
					if(objFile==0)
						delete outFile;
					else{
						((htmlFile*)objFile)->lockf(0);
						objFile=0;
					}
					outFile=0;
				}
				genericObject* fx=objects[code->object];
				if(fx!=0){
					if(fx->getType()==TYPPROXY){
						fx=((proxy*)fx)->getOriginal();
					}
					if(fx->getType()==TYPFILE){
						if((outFile = ((htmlFile*)fx)->getURL())!=0){
							((htmlFile*)fx)->lockf(1);
							objFile=fx;
							if(outFile->exists()==0)
								outFile->create();
							if(ivar){
								outFile->open();
								outFile->seekEND();
							}
						}else
							outFile=of;
					}
				}
			}
			break;
		case appendToFile:
			ivar=1;
			goto fileInit;
		case writeToFile:
			ivar=0;
fileInit:
			if (outFile!=of){
				if(objFile==0)
					delete outFile;
				else{
					((htmlFile*)objFile)->lockf(0);
					objFile=0;
				}
				outFile=0;
			}
			if(registerA){
				char fname[256];
				int i=0;
				while(registerA){
					strcpy(fname+i,*registerA);
					i+=strlen(fname+i);
					tmp1=registerA->next;
					delete registerA;
					registerA=tmp1;
				}
				if (stricmp(fname,"con")==0)
				  strcpy(fname,CONSOLE);
				i=strlen(fname)-1;
				for(;i>0 && fname[i]!=':' && fname[i]!= SLASH && fname[i]!= FSLASH ;--i);
				if(i==0)
					strcpy(fname,CONSOLE);
				outFile=new RealFile(fname);
				if(ivar==0)
					outFile->replace();
				else{
					outFile->open();
					outFile->seekEND();
				}
				if(outFile->open()==0){
					outFile->createUnique();
					if(outFile->open()==0){
						delete outFile;
						outFile=of;
						over=3;
					}
				}
			}
			break;
		case deleteObject:
				o=objects[code->object];
				if(o!=0 && o!=objs){
					if(stricmp(o->getName(),sUSERINFO)){
						if(objFile==o){
							((htmlFile*)objFile)->lockf(0);
							outFile=of;
							objFile=0;
						}
						objects[code->object]=deleteObjfast(o);							
					}
				}
			break;
		case registerFile:
			if(code->param){
				if(stricmp(getName(),(char*)*code->param)){
					char ffname[256];
					snprintf(ffname,256,"%s%c%s",templatePath,FSLASH,(char*)*code->param);
					File *f=new File(ffname);
					if(f->exists()){
						dhtmlCompiler *x=new dhtmlCompiler();
						if(stricmp(f->getExt(),"cch")){
							x->compile(f);
						}else{
							vFile *fi=new vFile(ffname,0,1);
							fi->getReal();
							compileEncrypted(fi,x);
							delete fi;
						}
						delete x;
					}
					delete f;
				}
			}
			break;
		case switchCase:
			acc++;
			acc->op=EQU;
			acc->type=1;
			if(registerA && registerA->isValid()){
				if(getbType(*registerA,&prec)<2){
					acc->x=atof(*registerA);
					acc->type=0;
					acc->prec=prec;
				}
			}else{
				deleteRegisterA;
				registerA=new htmlBuffer("");
			}
			acc->acc=registerA;
			do{
				char *b=*code->param;
				if(getbType(b,&prec)<2){
					facc=atof(b);
					ttype=0;
				}else{
					ttype=3;
				}
				if(compare(acc,0,facc,ttype,code->param,prec,objs)){
					b+=code->param->getSize();
					i=*((int*)b);
					goto casefound;
				}
				i++;
				code=codeBuff+i;
			}while(code->Instruction==switchCase);
			i--;
casefound:
			acc--;
			deleteRegisterA;
			break;
		case closeOutput:
			if(outFile != of){
				if(objFile==0)
					delete outFile;
				else{
					((htmlFile*)objFile)->lockf(0);
					objFile=0;
				}
				outFile=of;
			}
			break;
		case execp:
		case exec:
			if(code->param && registerB){
				int success=0;
				int returncode=0;
				htmlBuffer *tmp=registerA;
				while(tmp){
					returncode+=tmp->getSize()+3;
					tmp=tmp->next;
				}
				Buffer* pb=new Buffer(returncode+132);
				char *pars=*pb;
				char* prgname=pars+returncode+4;
				*pars=0;
				pars++;
				*pars=0;
				if(returncode){
					tmp=registerA;
					int n;
					while(tmp){
						if((code->Instruction==exec) && registerA->next)
							n=snprintf(pars,returncode,"\"%s\" ",(char*)*tmp);
						else{
							strcpy(pars,*tmp);
							n=strlen(pars);
						}
						pars+=n;
						returncode-=n;
						tmp=tmp->next;
					}
				}
				pars=*pb;
				snprintf(prgname,128,"%s%c%02d%lu.txt",tmpDirectory,FSLASH,instance,code);
				htmlObject *o = new htmlObject(new Buffer(*code->param,code->param->getSize()));
				addObject(o,&objects[code->object],objs,(int)code);
				RealFile *fx=new RealFile(prgname);
				fx->createUnique();
				snprintf(prgname,128,"%s%c%s",(*serverConfig)["bin"],FSLASH,(char*)(*registerB));
				ExecuteProgram(prgname,pars,returncode,success,fx);                          
				snprintf(prgname,16,"%d",success);
				o->putValue("success",prgname);
				snprintf(prgname,16,"%d",returncode);
				o->putValue("rc",prgname);
				for(int i=0;i<200 && fx->open()==0;++i)
					SleepMilSec(15);
				o->putValue(new Buffer("output",7),new htmlBuffer(fx));
				delete pb;
			}
			deleteRegisterB;
			deleteRegisterA;
			break;
		case execPrgm:
			if(code->param && registerA){
				int success;
				char prgname[128];
				char pars[32];
				snprintf(prgname,128,"%s%c%s.exe",(*serverConfig)["bin"],FSLASH,(char*)*registerA);
				HFILE r1=0,r2=0,w1=0,w2=0;
				int oz=0;
				pars[0]=0;
				pars[1]=0;
				char *input=pars+1;
				if(registerB){
					PipeCreate(r1,w1, 0xffff,success);
					if(success){
						genericObject* o = getObject(*registerB,objs);
						if(o!=0){
							if(o->getType()!=TYPXML){
								htmlBuffer* s=o->getValue(sPACKED);
								if(s){
									oz=s->getSize()-1;
									Write(w1,*s,oz);
								}
								delete s;
							}
						}
						FileClose(w1,success);
					}else
						printf("error creating pipe\n");
				}
				PipeCreate(r2,w2, 0xffff,success);
				if(success){
					int returncode=0;
					snprintf(input,8,"%d",w2); 
					if(r1 && oz)
						snprintf(input+strlen(input),20," %d %d",r1,oz);
					RealFile *fx=0;
					ExecuteProgram(prgname,pars,returncode,success,fx);                                 
					if (success){
						FileClose(w2,success);
						htmlObject *o= new htmlObject(new Buffer(*code->param,code->param->getSize()));
						fileStream *fs=new fileStream(r2,returncode);
						inputStream *in=new inputStream(fs);
						o->readForm(in);
						delete in;
						delete fs;
						addObject(o,&objects[code->object],objs,(int)code);
					}else{
						FileClose(w2,success);
						printf("Error [%02d] executing %s\n",success,prgname);
					}
					FileClose(r2,success);
				}
				if(r1!=0)
					FileClose(r1,success);
				deleteRegisterB;
				deleteRegisterA;
			}
			break;
		case packObjectA:
			if(code->param){
				if((o = objects[code->object])!=0){
					if(lc=(o->getType()==TYPPROXY)){
						o=((proxy*)o)->getOriginal();
						o->lock();
					}
					htmlBuffer* th=new htmlBuffer(sPACKED);
					registerA=o->getValue(th);
					if(lc)
						o->release();
					delete th;
				}else{
					snprintf(atmp,64,"%s()",(char*)*code->param);
					registerA=new htmlBuffer(atmp);
					registerA->setInvalid();
				}

			}
			break;
		case readMail:
			if(registerA && code->param){
				File *f=registerA->getFile();
				if(f==0){
					f=new File(*registerA);
					if(f->exists()==0){
						delete f;
						f=0;
					}else{
						deleteRegisterA;
						registerA=new htmlBuffer(f);
					}
				}
				if(f!=0){
					htmlObject *o=new htmlObject(new Buffer(*code->param,code->param->getSize()));
					o->putValue("method","data");
					fileStream *fs=new fileStream(f);
					f->seekTo(0);
					inputStream *in=new inputStream(fs);
					o->readMail(in);
					delete fs;
					delete in;
					addObject(o,&objects[code->object],objs,(int)code);
				}
			}
			deleteRegisterA;
			break;
		case unpackVar:	over++;
		case unpackForm:over++;
		case unpackMail:
			if(registerA && code->param){
				File *f=registerA->getFile();
				if(f==0){
					f=new File(*registerA);
					if(f->exists()==0){
						delete f;
						f=0;
					}else{
						deleteRegisterA;
						registerA=new htmlBuffer(f);
					}
				}
				if(f!=0){
					htmlObject *o=0;
					if(over==2)
						o = new htmlObject(new Buffer(*code->param,strlen(*code->param)+1));
					else
						if(over==1)
							o = new htmlForm(new Buffer(*code->param,strlen(*code->param)+1),event,objs);
						else
							if(over==0)
								o = new htmlMail(new Buffer(*code->param,strlen(*code->param)+1),event);
					fileStream *fs=new fileStream(f);
					f->seekTo(0);
					inputStream *in=new inputStream(fs);
					o->readForm(in);
					delete fs;
					delete in;
					addObject(o,&objects[code->object],objs,(int)code);
				}
			}
			over=0;
			deleteRegisterA;
			break;
		case NOP:
			deleteRegisterA;
			deleteRegisterB;
			deleteRegisterC;
			break;
		case rebuild:
			rebuildSearch();
			break;
		case flushData:
			caravanLocked=1;
			editLocked=1;
			editLock->lock();
			while(closeFiles())
				SleepMilSec(1000);
			break;
		case dispatch:
			{
				htmlBuffer *df=0;
				if(registerA!=0){
					if(registerA->getFile()==0){
						File *f = new File(*registerA);
						if (f->exists())
							df=new htmlBuffer(f);
						else{
							delete f;
							if(registerA->isValid()){
								df=registerA;
								registerA=0;
							}
						}
						deleteRegisterA;
						registerA=df;
					}
				}
			}
			over=1;
		case redirect:
			if(registerA){
				o = objects[code->object];
				if(o==0){
					o=new htmlObject(new Buffer(sRESPONSE,RESPONSEl));
					addObject(o,&objects[code->object],objs,(int)code);
				}
				if(over==0)
					o->putValue(redirected,registerA);
				else
					o->putValue(attached,registerA);
			}
			over=1;
			rc=1;
			break;
		case jmpIfNotTrue:
			acc->op=-1;
			if(acc->type==0){
				if(acc->x==0){
					i=(int)code->param;	
				}
				deleteRegisterA;
				break;
			}else{
				registerA=acc->acc;
				acc->acc=0;
			}
		case jmpIfValueZero:
			if(registerA && (registerA->isValid()!=0)){
				htmlBuffer* tmp=registerA;
				while(tmp){
					if(tmp->getSize()>1)
						goto valOK;
					tmp=tmp->next;
				}
			}
			i=(int)code->param;
valOK:
			deleteRegisterA;
			break;
		case chkIfObjZero:
			if(code->param){
				if((o = objects[code->object])!=0)
					registerA=new htmlBuffer("1");
			}
			break;
		case sjmp:
			while(codeBuff[i].Instruction==jmp || codeBuff[i].Instruction==sjmp)
				i=(int)codeBuff[i].param+1;
			code->param=(Buffer*)(--i);
			code->Instruction=jmp;
			break;
		case jmpLabel:
			if(quitLoop){
				over=1;
				rc=1;
				break;
			}
		case ejmp:
		case jmp:
			i=(int)code->param;
			break;
		case SleepSec:
			{
			int n=(int)code->param;
			SleepMilSec(n*1000);
			}
			break;
   }
 }
 if(mlocked)
	 mlock->release();
 objs->putValue(SYMINFO,NULLVALUE);
 saveMode(xSpace);
 if(outFile!=of && objFile==0)
		 delete outFile;
 editLock->lock();
 lock--;
 decActiveCount(getName());
 editLock->release();
 if(editLocked)
	 editLock->release();
 caravanLocked=0;
 if(rc && objs){
	 objs->putValue(sTerminate,"yes");
 }
}


void startScheduler()
{
  new scheduler();
}



vFile * getvFile(int);

void compileEmbedded(dhtmlCompiler* x)
{
	for(int i=0;i<16;++i){
	  vFile *f=getvFile(i);
	  if(f==0)
		  break;
	  compileEncrypted(f,x);
	  f->deleteFile();
	  delete f;
	}
}



void initDynamo()
{
	editLock=new mutex();
	dhtmlCompiler *x=new dhtmlCompiler();
//	mallocInternal=1;
	compileEmbedded(x);
	char *flike="*.cch";
	for(int  ftype=0;ftype<2;++ftype){
		finder* f = new finder(templatePath);
		if (f->findFile(flike)){
			int h=0;
			do{
				char *ffname=f->getFullName();
				if(ftype){
					File *f=new File(ffname);
					x->compile(f);     
					delete f;
				}
				else{
					vFile *fi=new vFile(ffname,0,1);
					fi->getReal();
					compileEncrypted(fi,x);
					delete fi;
				}
			}while(f->find());
		}
		delete f;
		flike="*";
	}
//	mallocInternal=0;
	delete x;
}
